插入&使用嵌套`belongs_to`关联的强参数进行更新

时间:2013-08-09 00:47:32

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

我有一个学生可以报名参加课程的表格。当用户提交表单时,他就会注册该课程并保存他的付款信息。换句话说,创建了Enrollment对象并更新了Student对象...除了我无法更新Student。这可能吗?如果是这样,怎么样?

我的模特......

class Student < ActiveRecord::Base
    has_many :enrollments
end

class Enrollment < ActiveRecord::Base
    belongs_to :student
    accepts_nested_attributes_for :student
end

我的(缩写)表格......

<%= form_for :enrollment, html: { id: "enrollment_form" } do |f| %>

    <%= f.fields_for :student_attributes do |student_builder| %>
        <%= student_builder.hidden_field :payment_name %>
    <% end %>

    <%= f.hidden_field :payment_token %>

    <div class="field terms">
        <%= f.check_box :agreed_to_terms %>
        <%= f.label :agreed_to_terms, "I agree to the terms and conditions." %>
    </div>

<% end %>

我的控制器......

class EnrollmentsController < ApplicationController

  def create
    @enrollment = Enrollment.new(enrollment_params)
    @enrollment.clazz_id = @clazz.id
    @enrollment.student_id = @student.id
    @enrollment.save
  end

  private
    def enrollment_params
      params.require(:enrollment).permit(:payment_token, :agreed_to_terms, student_attributes: [:payment_name])
    end
end

POST参数......

{
  "enrollment"=> {
    "student_attributes"=> {
      "payment_name"=> "MasterCard ending in 9840"
    },
    "payment_token"=> "CC11ho86XxVqsUW7Cn9YjCHg?1376007969212",
    "agreed_to_terms"=> "1"
  },
  "clazz_id"=> "7"
}

我在表单构建器中尝试了studentstudents_attributes的每个排列,但它们似乎都不起作用。

1 个答案:

答案 0 :(得分:5)

好的,我看到了一些事情:

  1. 嵌套属性,如[{3}}中所述,“允许您保存相关记录的属性通过 父级。”这意味着

    class Enrollment < ActiveRecord::Base
        belongs_to :student
        accepts_nested_attributes_for :student
    end
    

    本身无法正常工作,因为您尝试接受来自父级的嵌套属性。因此,您需要首先重新考虑Active Record的配置。

    如果我们假装全部被平方,那么更多的语法错误是:

  2. 替换

    <%= f.fields_for :student_attributes do |student_builder| %>
    

    <%= f.fields_for :students do |student_builder| %>
    

    这可能令人困惑,但将:students传递给fields_for助手会调用嵌套的学生对象,而:student_attributes是来自fields_for生成的POST参数的哈希键

  3. 在您的强参数中,您还需要允许学生:id,以便您的更新操作有参考。否则,它只会创建一个新学生。所以把它改成

    private
      def enrollment_params
        params.require(:enrollment).permit(:payment_token, :agreed_to_terms, student_attributes: [:payment_name, :id])
      end
    
  4. 我不确定这是否一切,但希望这是一个开始。祝你好运。