Tengo un Bill
objeto, que tiene muchos Due
objetos. El Due
objeto también pertenece a a Person
. Quiero un formulario que pueda crear el Bill
y sus elementos secundarios Dues
en una sola página. Estoy tratando de crear un formulario utilizando atributos anidados, similares a los de este Railscast .
El código relevante se enumera a continuación:
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
facturas_controlador.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 %>
facturas / _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>
ACTUALIZAR a bills_controller.rb ¡ Esto funciona!
def bill_params
params
.require(:bill)
.permit(:company, :month, :year, dues_attributes: [:amount, :person_id])
end
Los campos adecuados se representan en la página (aunque Person
todavía no hay un menú desplegable ) y el envío es exitoso. Sin embargo, ninguna de las cuotas secundarias se guarda en la base de datos y se genera 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?
fuente
Respuestas:
Parece que hay un cambio en el manejo de la protección de atributos y ahora debe incluir en la lista blanca los parámetros en el controlador (en lugar de attr_accessible en el modelo) porque la antigua gema opcional strong_parameters se convirtió en parte del Rails Core.
Esto debería verse más o menos así:
Entonces
params.require(:model).permit(:fields)
sería usadoy para atributos anidados algo como
Se pueden encontrar más detalles en los documentos de la API de Ruby edge y strong_parameters en github o aquí
fuente
def bill_params params.require(:bill).permit(:company, :month, :year, :dues_attributes[:amount, :person_id]) end
ahora recibo este error: no hay conversión implícita de Symbol en Integerpets_attributes: [:id, :name, :category]
De lo contrario, cuando edite, cada mascota se creará nuevamente.Person.create(person_params)
o no llamará al método. En cambio, lo conseguirásActiveModel::ForbiddenAttributesError
.:_destroy
parámetro oculto . es decirpets_attributes: [:id, :name, :category, :_destroy]
De los documentos
Los atributos anidados tienen la forma de un hash. En mi aplicación, tengo un modelo Question.rb que acepta atributos anidados para un modelo Answer.rb (donde el usuario crea opciones de respuesta para una pregunta que crea). En el question_controller, hago esto
Se permite todo en el hash de la pregunta, incluidos los atributos de respuesta anidados. Esto también funciona si los atributos anidados tienen forma de matriz.
Dicho esto, me pregunto si hay un problema de seguridad con este enfoque porque básicamente permite todo lo que está dentro del hash sin especificar exactamente qué es, lo que parece contrario al propósito de los parámetros fuertes.
fuente
.permit!
la única opción? No puedo hacer que funcione incluso con todos los atributos del modelo permitidos porque se ahoga en la matriz.o simplemente puedes usar
fuente
En realidad, hay una forma de incluir en la lista blanca todos los parámetros anidados.
Este método tiene ventaja sobre otras soluciones. Permite permitir parámetros profundamente anidados.
Mientras que otras soluciones como:
No lo hagas
Fuente:
https://github.com/rails/rails/issues/9454#issuecomment-14167664
fuente
Hoy me encontré con este mismo problema, mientras trabajaba en los rieles 4, pude hacerlo funcionar estructurando mis campos_por:
Luego, en mi controlador, tengo mis parámetros fuertes como:
Todo funciona!
fuente
Si usa un campo JSONB, debe convertirlo a JSON con .to_json (ROR)
fuente