simple_form has_many通过未经许可的参数

时间:2015-10-02 02:08:27

标签: ruby-on-rails simple-form nested-attributes

我在设置创建/更新的简单方面遇到了一些麻烦。这是表格:

<%= simple_form_for( setup_menu(@menu) ) do |f| %>

<%= f.input :user_id, :as => :hidden %>
<%= f.input :name %>
<%= f.input :description %>

<%= f.association :recipes %>

<%= f.button :submit %>
<% end %>

以下是三种模式:

class Menu < ActiveRecord::Base
  has_many :courses
  has_many :recipes, through: :courses

  accepts_nested_attributes_for :recipes,
    reject_if: :all_blank

  accepts_nested_attributes_for :courses,
    reject_if: :all_blank
end
class Recipe < ActiveRecord::Base
  has_many :courses
  has_many :menus, through: :courses

  accepts_nested_attributes_for :menus 
end
class Course < ActiveRecord::Base
    belongs_to  :menu
    belongs_to  :recipe
end

这是来自menus_controller的params定义:

    def menu_params
      params.require(:menu).permit(:user_id, :name, :description, :recipe_ids, :course_ids, :courses, :recipes,
        recipes_attributes: [:id, :recipe_id, :_destroy],     courses_attributes: [:id, :recipe_id, :menu_id, :_destroy]
      )
    end

我一直在recipe_ids上获得一个未经许可的参数错误。

Started PATCH "/menus/1" for ::1 at 2015-10-01 20:54:56 -0500
Processing by MenusController#update as HTML
  Parameters: {"utf8"=>"√", "authenticity_token"=>"i/7E27BWul9trszURDu1z8PtsHaG54byG9JOlEp3mn2oQZVveM2mSP4XTLzjWKAK+BNvwoi/pqBbQPrPTcnaDw==", "menu"=>{"name"=>"Menu 1", "description"=>"First test menu", "recipe_ids"=>["", "1", "3", "4"]}, "
commit"=>"Update Menu", "id"=>"1"}
  Menu Load (1.0ms)  SELECT  "menus".* FROM "menus" WHERE "menus"."id" = ? LIMIT 1  [["id", 1]]
Unpermitted parameter: recipe_ids
   (1.0ms)  begin transaction
   (0.0ms)  commit transaction
Redirected to http://localhost:3000/menus/1
Completed 302 Found in 11ms (ActiveRecord: 2.0ms)

我确信这是我错过的简单事。我一整天都在摸不着头脑。有人可以帮忙吗?

2 个答案:

答案 0 :(得分:1)

我知道这很简单。这解决了整个问题。

params.require(:menu).permit(:user_id, :name, :description, { :recipe_ids => [] } )

答案 1 :(得分:0)

要添加到您的答案中,您的结构存在许多问题。

<强>对象

您在视图中呼叫setup_menu;这应该至少在您的控制器中调用(除非您使用部分...即使那时它应该作为本地var传递)。

<%= simple_form_for @menu do |f| %>
   <%= f.hidden_field :user_id %>
   <%= f.input :name %>
   <%= f.input :description %>

   <%= f.association :recipes %>

   <%= f.button :submit %>
<% end %>

必须使用适当的控制器操作进行备份。同样,如果您在partial之内使用此功能,则可以在定义@menu的同时分配操作:

#app/controllers/menus_controller.rb
class MenusController < ApplicationController
   def new
      @menu = setup_menu x
   end
end

关联数据

由于您使用的是has_many :recipes关联,因此您应该能够在强大的参数中设置:recipes。如果不这样做,你的recipe_ids应该没问题,但我认为你在括号中的封装是不正确的:

params.require(:menu).permit(:user_id, :name, :description, recipe_ids: [])

顺便说一句,如果您设置了has_and_belongs_to_many关系,则可以按以下方式传递recipes

params.require(:menu).permit(:user, :name, :description, :recipes)

我认为没有理由说这不适用于您的has_many :through

<强>解释

最后,您应该能够在模型中为accepts_nested_attributes_for设置多个定义:

#app/models/menu.rb
class Menu < ActiveRecord::Base
  has_many :courses
  has_many :recipes, through: :courses

  accepts_nested_attributes_for :recipes, :courses, reject_if: :all_blank
end

保持代码高效的最重要,最简单的方法之一是使其可读。上面是一个例子 - repeating yourself unnecessarily不仅使你的代码混乱,而且妨碍了有效的管理。