Atributos anidados parámetros no permitidos
Tengo un objeto Bill
, que tiene muchos objetos Due
. El objeto Due
también pertenece a un Person
. Quiero un formulario que pueda crear el Bill
y sus hijos Dues
todo en una página. Estoy intentando crear un formulario usando atributos anidados, similares a los de este Railscast.
Se indica el código pertinente abajo:
Debido.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
Facturas / _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>
ACTUALIZACIÓN a bills_controller.rb Esto funciona!
def bill_params
params
.require(:bill)
.permit(:company, :month, :year, dues_attributes: [:amount, :person_id])
end
Los campos apropiados se muestran en la página (aunque sin un menú desplegable para Person
todavía) y el envío es exitoso. Sin embargo, ninguna de las cuotas de los niños se guardan para la base de datos, y se lanza un error en el registro del servidor:
Unpermitted parameters: dues_attributes
Justo antes del error, el registro muestra esto:
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"}
¿Ha habido algún cambio en Rails 4?
6 answers
Parece que hay un cambio en el manejo de la protección de atributos y ahora debe incluir parámetros en la lista blanca en el controlador (en lugar de attr_accessible en el modelo) porque la antigua gema opcional strong_parameters se convirtió en parte del núcleo de Rails.
Esto debería ser algo como esto:
class PeopleController < ActionController::Base
def create
Person.create(person_params)
end
private
def person_params
params.require(:person).permit(:name, :age)
end
end
Así que params.require(:model).permit(:fields)
se usaría
Y para atributos anidados algo como
params.require(:person).permit(:name, :age, pets_attributes: [:id, :name, :category])
Se pueden encontrar más detalles en los documentos de la API de Ruby edge y strong_parameters en github o aquí
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-25 07:39:56
De los documentos
To whitelist an entire hash of parameters, the permit! method can be used
params.require(:log_entry).permit!
Los atributos anidados tienen la forma de un hash. En mi aplicación, tengo una pregunta.el modelo rb acepta atributos anidados para una respuesta.modelo rb (donde el usuario crea opciones de respuesta para una pregunta que crea). En questions_controller, hago esto
def question_params
params.require(:question).permit!
end
Todo en el hash de la pregunta está permitido, incluyendo los atributos de respuesta anidados. Esto también funciona si los atributos anidados tienen la forma de una matriz.
Dicho esto, me pregunto si hay una preocupación de seguridad con este enfoque porque básicamente permite cualquier cosa que esté dentro del hash sin especificar exactamente qué es, lo que parece contrario al propósito de los parámetros fuertes.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-06-24 02:50:47
O simplemente puede usar
def question_params
params.require(:question).permit(team_ids: [])
end
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-08-31 14:20:04
En realidad, hay una forma de enumerar todos los parámetros anidados.
params.require(:widget).permit(:name, :description).tap do |whitelisted|
whitelisted[:position] = params[:widget][:position]
whitelisted[:properties] = params[:widget][:properties]
end
Este método tiene ventaja sobre otras soluciones. Permite permitir parámetros anidados profundamente.
Mientras que otras soluciones como:
params.require(:person).permit(:name, :age, pets_attributes: [:id, :name, :category])
No lo hagas.
Fuente:
Https://github.com/rails/rails/issues/9454#issuecomment-14167664
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-09-25 20:56:30
Hoy me encontré con este mismo problema, mientras trabajaba en rails 4, pude hacerlo funcionar estructurando mis fields_for como:
<%= f.select :tag_ids, Tag.all.collect {|t| [t.name, t.id]}, {}, :multiple => true %>
Entonces en mi controlador tengo mis fuertes parámetros como:
private
def post_params
params.require(:post).permit(:id, :title, :content, :publish, tag_ids: [])
end
¡Todo funciona!
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-09-19 21:14:59
Si utiliza un campo JSONB, debe convertirlo a JSON con .to_json (ROR)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-03-16 16:34:27