【问题标题】:Adding a reference to an existing record in has_many through: association通过:关联添加对 has_many 中现有记录的引用
【发布时间】:2017-03-16 01:55:18
【问题描述】:

我想要一个表单,通过使用 Ruby on Rails 4 搜索字段,将现有记录添加到 has_many。

我的模型如下:

class Offering < ActiveRecord::Base
  has_many :students, through: :enrolments
  has_many :enrolments
end

class Enrolment < ActiveRecord::Base
  belongs_to :offering
  belongs_to :student
end

class Student < ActiveRecord::Base
  has_many :offerings, through: :enrolments
  has_many :enrolments
end

在我的既定课程的显示页面上,我想要一个“按学生 ID 添加学生”表单。用户将输入学生的学生 ID(即 而不是 rails 记录的 ID),然后提交以添加关联。

(理想情况下,页面会在输入有效的学生 ID 并在提交之前自动显示要添加的学生的全名)

但我是新手,我不知道如何进行设置。我的期望是这样的:

<h4>Add Student</h4>
<%= form_for @offering do |f| %>
  <p>
    Student ID: <%= f.text_field @sid %><br>
  </p>
  <p>
    <%= f.submit "Add Student" %>
  </p>
<% end %>

其中 sid 是一个局部变量,我可以使用它在控制器中查找学生并使用 @offering.students &lt;&lt; Student.search() 添加。

但我不确定,如果有任何帮助,我将不胜感激。谢谢!

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-4


    【解决方案1】:

    我遇到了类似的挑战,并使用 simple_form gem 和一个小 Jquery 解决了它。

    我的模型中的 has_many :through 关联与您的具有相同的结构,但在父模型和连接模型中包含“accepts_nested_attributes_for”类方法。在您的情况下,它将是:

    class Offering < ActiveRecord::Base
      has_many :students, through: :enrolments
      has_many :enrolments
      accepts_nested_attributes_for :enrolments
    end
    
    class Enrolment < ActiveRecord::Base
      belongs_to :offering
      belongs_to :student
      accepts_nested_attributes_for :students
    end
    
    class Student < ActiveRecord::Base
      has_many :offerings, through: :enrolments
      has_many :enrolments
    end
    

    我还需要做一些事情来根据另一个输入的值动态创建关联(在您的情况下,用于输入学生 ID 的文本输入):

    1.将关联表单助手添加到我的视图中。 使用 simple_fields_for 和关联助手在 Offering#show 视图中“嵌套” Enrollment 和 Student 表单字段(当我在父模型的 _form 中包含以下代码时,这对我有用部分,即使您将其添加到 show.html.erb 文件):

    <%= simple_form_for @offering do |f| %>
        <h4>Add Student</h4>
        <%= f.simple_fields_for :enrolments do |e| %>
            <p>Student ID: <%= text_field_tag 'sid' %><br><span id="student_name"></span></p>
            <span style="display:none;"><%= e.association :student, collection: [] %></span>
        <% end %>
        <p><%= f.submit "Add Student" %></p>
     <% end %>
    

    2。创建 AJAX 调用以动态写入视图。 向父模型的 js.coffee 文件添加 ajax 调用以使用文本输入的值动态创建关联:

    # offering.js.coffee
    
    $('form').on 'blur', '[id="sid"]', (event) ->
            $.ajax
              url: '/set_student_id/'
              type: 'GET'
              dataType: 'json'
              json: true
              data: {student_id: $("input[id='sid']").val()}
              success: (data) ->
                $("[id$='student_id']").html(data.sid)
                $("[id='student_name']).html(data.name)
              error: (data) ->
                console.log "error"
    

    3.在父模型的控制器中添加一个操作来处​​理 ajax 调用。 使用与该操作的 ajax 调用中的“url”值相同的名称(并确保允许加入和子模型属性):

    # offerings_controller.rb
    
    def set_student_id
        student = Student.find_by(sid: params[:student_id])
        @sid = "<option value='#{student.id}' selected='selected'>#{student.name}</option>"
        respond_to do |format|
            format.json { render json: {sid: @sid, name: student.name} }
        end
    end
    
    def offering_params
        params.require(:offering).permit(enrolments_attributes:[:id, :student_id, students_attributes: [:id, :name]])
    end
    

    4.为 ajax 回调更新 /config/routes.rb 文件。确保您在 ajax 调用中包含的“url”值被路由到父模型控制器中的正确操作:

    get "/set_student_id/", to: "offerings#set_student_id"
    

    Simple Form 关联助手默认创建一个选择列表。此代码应动态添加与作为选定选项输入的 sid 匹配的学生,并在输入失去焦点(jquery 中的模糊事件)时动态显示 sid 表单输入下方的学生名称。

    希望这会有所帮助。

    【讨论】:

      猜你喜欢
      • 2014-12-27
      • 2011-11-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多