IT

허용되지 않은 중첩 속성

lottoking 2020. 7. 5. 07:47
반응형

허용되지 않은 중첩 속성


Bill많은 Due객체 가있는 객체가 있습니다. Due객체도에 속한다 Person. 한 페이지에 Bill및 그 자식을 Dues모두 만들 수있는 양식을 원합니다 . 이 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에 약간의 변화가 있었습니까?


Seems there is a change in handling of attribute protection and now you must whitelist params in the controller (instead of attr_accessible in the model) because the former optional gem strong_parameters became part of the Rails Core.

This should look something like this:

class PeopleController < ActionController::Base
  def create
    Person.create(person_params)
  end

private
  def person_params
    params.require(:person).permit(:name, :age)
  end
end

So params.require(:model).permit(:fields) would be used

and for nested attributes something like

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

Some more details can be found in the Ruby edge API docs and strong_parameters on github or here


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.


or you can simply use

def question_params

  params.require(:question).permit(team_ids: [])

end

Actually there is a way to just white-list all nested parameters.

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

This method has advantage over other solutions. It allows to permit deep-nested parameters.

While other solutions like:

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

Don't.


Source:

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


Today I came across this same issue, whilst working on rails 4, I was able to get it working by structuring my fields_for as:

<%= f.select :tag_ids, Tag.all.collect {|t| [t.name, t.id]}, {}, :multiple => true %>

Then in my controller I have my strong params as:

private
def post_params
    params.require(:post).permit(:id, :title, :content, :publish, tag_ids: [])
end

All works!


If you use a JSONB field, you must convert it to JSON with .to_json (ROR)

참고URL : https://stackoverflow.com/questions/15919761/nested-attributes-unpermitted-parameters

반응형