【问题标题】:How to use Rails 4 strong parameters with has_many :through association?如何使用带有has_many的Rails 4强参数:通过关联?
【发布时间】:2013-07-02 21:39:48
【问题描述】:

我在获取 has_many 时遇到了麻烦:通过关联使用 Rails 4 的强参数。我有一个名为 Checkout 的模型,我需要在新的结帐表单中从 Employee 模型中选择一个人。 Checkouts 和Employees 通过Employment 模型关联。

我在尝试创建新结帐时收到此错误:

NoMethodError in CheckoutsController#create
undefined method `employee' for #<Checkout:0x007ff4f8d07f88>

我的创建操作、结帐参数或新结帐表单似乎有问题。这是创建操作:

  def create    
    @user = current_user
    @checkout = @user.checkouts.build(checkout_params)

    respond_to do |format|
      if @checkout.save
        format.html { redirect_to @checkout, notice: 'Checkout was successfully created.' }
      else
        format.html { render action: 'new' }
      end
    end
  end

我的结帐参数:

def checkout_params
      params.require(:checkout).permit(:job, :employee_ids, :shift, :date, :hours, :sales, :tips, :owed, :collected, :notes)
end

我的新结帐表格:

<div class="field">
     <%= f.label :employee %><br>
     <%= f.collection_select(:employee_ids, Employee.all.collect, :id, :full_name, {:prompt => "Please select"} ) %>
</div>

但我无法弄清楚 Rails 4 和强大的参数发生了什么变化。在 Rails 3 中,这种类型的关联和表单使用 attr_accessible 而不是 strong_parameters 对我有用。

相关文件

错误的完整跟踪: https://gist.github.com/leemcalilly/0cb9e2b539f9e1925a3d

模型/checkout.rb: https://gist.github.com/leemcalilly/012d6eae6b207beb147a

控制器/checkouts_controller.rb: https://gist.github.com/leemcalilly/a47466504b7783b31773

views/checkouts/_form.html.erb https://gist.github.com/leemcalilly/ce0b4049b23e3d431f55

模型/employee.rb: https://gist.github.com/leemcalilly/46150bee3e6216fa29d1

控制器/employees_controller.rb: https://gist.github.com/leemcalilly/04f3acdac0c9a678bca8

模型/employment.rb: https://gist.github.com/leemcalilly/6adad966dd48cb9d1b39

db/schema.rb: https://gist.github.com/leemcalilly/36be318c677bad75b211

【问题讨论】:

标签: activerecord many-to-many ruby-on-rails-4 strong-parameters


【解决方案1】:

请记住,您为强参数(employees、employee_ids 等)指定的名称在很大程度上是无关紧要的,因为它取决于选择提交的名称。根据命名约定,强参数没有“魔法”。

https://gist.github.com/leemcalilly/a71981da605187d46d96 在 'employee_ids' 上引发“Unpermitted parameter”错误的原因是因为它需要一个标量值的数组,根据https://github.com/rails/strong_parameters#nested-parameters,而不仅仅是一个标量值。

# If instead of:
... "employee_ids" => "1" ...
# You had:
... "employee_ids" => ["1"]

那么你的强参数就会起作用,具体来说:

... { :employee_ids => [] } ...

因为它接收的是一个标量值数组,而不仅仅是一个标量值。

【讨论】:

    【解决方案2】:

    好的,所以我实际上不需要嵌套参数。这就是最终为我工作的:

    # Never trust parameters from the scary internet, only allow the white list through.
    def checkout_params
      params.require(:checkout).permit(:job, :shift, :employee_ids, :date, :hours, :sales, :tips, :owed, :collected, :notes)
    end
    

    以下是有效的更改组合。

    仍然不太明白为什么这会奏效。

    【讨论】:

    • 因为你提交的不是ID列表...请参考我之前的解释。
    • 哦,所以在这个线程的开头我试图提交:employee_id,而它应该是:employee_ids。我从来不需要嵌套属性,对吧?
    • 正确,除了命名之外,您永远不需要嵌套属性,因为您只提交一个标量值。
    【解决方案3】:

    我可以发布我在其中一个控制器中使用的许可声明。这也有一个多对多的关联。您嵌套了 permit 数组。在您的许可声明中使用查找关联。唯一的区别应该是你的不会被嵌套第三次。

    就我而言,协会 引用 has_many :quote_items

    QuoteItems has_many :quote_options, :through =&gt; quote_item_quote_options.

    quotes_controller.rb

    params.require(:quote).permit(:quote_date, :good_through, :quote_number, quote_items_attributes: [:id,:quote_id, :item_name, :material_id, quote_item_quote_options_attributes:[:quote_option_id,:quote_item_id,:qty,:_destroy,:id]])
    

    【讨论】:

    • 好的,基于此,这似乎对我有用params.require(:checkout).permit(:job, :shift, :date, :hours, :sales, :tips, :owed, :collected, :notes, employees_attributes: [:id, :first_name, :last_name, :number ]),但我仍然收到undefined method "employee" 错误。我已经尝试了所有这些变体,但仍然出现该错误:gist.github.com/leemcalilly/91ab475cf2a9e819724e。根据强大的参数文档github.com/rails/strong_parameters#nested-parameters,我似乎可以只使用{:employees =&gt; []},但这也不起作用。
    猜你喜欢
    • 1970-01-01
    • 2015-11-16
    • 2013-05-06
    • 2014-12-16
    • 2013-11-24
    • 2015-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多