128

Bill多くのオブジェクトを持つオブジェクトがありますDue。オブジェクトはDueにも属しますPersonBillとその子Duesをすべて 1 ページで作成できるフォームが必要です。この Railscastのものと同様に、ネストされた属性を使用してフォームを作成しようとしています。

関連するコードを以下に示します。

due.rb

class Due < ActiveRecord::Base
    belongs_to :person
    belongs_to :bill
end

bill.rb

class Bill < ActiveRecord::Base
    has_many :dues, :dependent => :destroy 
    accepts_nested_attributes_for :dues, :allow_destroy => true
end

bills_controller.rb

  # GET /bills/new
  def new
      @bill = Bill.new
      3.times { @bill.dues.build }
  end

bills/_form.html.erb

  <%= form_for(@bill) do |f| %>
    <div class="field">
        <%= f.label :company %><br />
        <%= f.text_field :company %>
    </div>
    <div class="field">
        <%= f.label :month %><br />
        <%= f.text_field :month %>
    </div>
    <div class="field">
        <%= f.label :year %><br />
        <%= f.number_field :year %>
    </div>
    <div class="actions">
        <%= f.submit %>
    </div>
    <%= f.fields_for :dues do |builder| %>
        <%= render 'due_fields', :f => builder %>
    <% end %>
  <% end %>

bills/_due_fields.html.erb

<div>
    <%= f.label :amount, "Amount" %>        
    <%= f.text_field :amount %>
    <br>
    <%= f.label :person_id, "Renter" %>
    <%= f.text_field :person_id %>
</div>

bills_controller.rb への更新 これは機能します!

def bill_params 
  params
  .require(:bill)
  .permit(:company, :month, :year, dues_attributes: [:amount, :person_id]) 
end

適切なフィールドがページにレンダリングされ (Personまだドロップダウンはありませんが)、送信が成功します。ただし、子供の会費はデータベースに保存されず、サーバー ログにエラーがスローされます。

Unpermitted parameters: dues_attributes

エラーの直前に、ログに次のように表示されます。

Started POST "/bills" for 127.0.0.1 at 2013-04-10 00:16:37 -0700
Processing by BillsController#create as HTML<br>
Parameters: {"utf8"=>"✓", 
"authenticity_token"=>"ipxBOLOjx68fwvfmsMG3FecV/q/hPqUHsluBCPN2BeU=",
 "bill"=>{"company"=>"Comcast", "month"=>"April ", 
"year"=>"2013", "dues_attributes"=>{
"0"=>{"amount"=>"30", "person_id"=>"1"}, 
"1"=>{"amount"=>"30", "person_id"=>"2"},
 "2"=>{"amount"=>"30", "person_id"=>"3"}}}, "commit"=>"Create Bill"}

Rails 4 に変更はありますか?

4

6 に答える 6

23

From the docs

To whitelist an entire hash of parameters, the permit! method can be used

params.require(:log_entry).permit!

Nested attributes are in the form of a hash. In my app, I have a Question.rb model accept nested attributes for an Answer.rb model (where the user creates answer choices for a question he creates). In the questions_controller, I do this

  def question_params

      params.require(:question).permit!

  end

Everything in the question hash is permitted, including the nested answer attributes. This also works if the nested attributes are in the form of an array.

Having said that, I wonder if there's a security concern with this approach because it basically permits anything that's inside the hash without specifying exactly what it is, which seems contrary to the purpose of strong parameters.

于 2013-06-24T02:43:58.573 に答える
13

実際には、ネストされたすべてのパラメーターをホワイトリストに登録する方法があります。

params.require(:widget).permit(:name, :description).tap do |whitelisted|
  whitelisted[:position] = params[:widget][:position]
  whitelisted[:properties] = params[:widget][:properties]
end

この方法は、他のソリューションよりも優れています。深くネストされたパラメーターを許可できます。

他のソリューションは次のようになります。

params.require(:person).permit(:name, :age, pets_attributes: [:id, :name, :category])

しないでください。


ソース:

https://github.com/rails/rails/issues/9454#issuecomment-14167664

于 2014-09-25T20:56:30.630 に答える