activerecord - permit - strong params rails
Cómo usar Rails 4 parámetros fuertes con has_many: ¿a través de la asociación? (3)
Tengo problemas para obtener has_many: a través de una asociación que trabaja con los parámetros potentes de Rails 4. Tengo un modelo llamado Checkout
y necesito seleccionar una persona del modelo de Employee
en el nuevo formulario de pago. Las cajas y los empleados se asocian a través de un modelo de Employment
.
Recibo este error cuando intento crear un nuevo pago:
NoMethodError in CheckoutsController#create
undefined method `employee'' for #<Checkout:0x007ff4f8d07f88>
Parece que hay algún problema con mi acción de creación, mis parámetros de pago o mi nuevo formulario de pago. Aquí está la acción de crear:
def create
@user = current_user
@checkout = @user.checkouts.build(checkout_params)
respond_to do |format|
if @checkout.save
format.html { redirect_to @checkout, notice: ''Checkout was successfully created.'' }
else
format.html { render action: ''new'' }
end
end
end
Mis parámetros de pago:
def checkout_params
params.require(:checkout).permit(:job, :employee_ids, :shift, :date, :hours, :sales, :tips, :owed, :collected, :notes)
end
Mi nuevo formulario de pago:
<div class="field">
<%= f.label :employee %><br>
<%= f.collection_select(:employee_ids, Employee.all.collect, :id, :full_name, {:prompt => "Please select"} ) %>
</div>
Pero no puedo entender qué ha cambiado con Rails 4 y los parámetros fuertes. En Rails 3 este tipo de asociación y forma funcionó para mí usando attr_accessible en lugar de strong_parameters.
Archivos Relevantes
Rastreo completo del error: https://gist.github.com/leemcalilly/0cb9e2b539f9e1925a3d
models / checkout.rb: https://gist.github.com/leemcalilly/012d6eae6b207beb147a
controllers / checkouts_controller.rb: https://gist.github.com/leemcalilly/a47466504b7783b31773
views / checkouts / _form.html.erb https://gist.github.com/leemcalilly/ce0b4049b23e3d431f55
models / employee.rb: https://gist.github.com/leemcalilly/46150bee3e6216fa29d1
controladores / employees_controller.rb: https://gist.github.com/leemcalilly/04f3acdac0c9a678bca8
models / employment.rb: https://gist.github.com/leemcalilly/6adad966dd48cb9d1b39
db / schema.rb: https://gist.github.com/leemcalilly/36be318c677bad75b211
Ok, entonces realmente no necesitaba anidar los parámetros. Esto es lo que terminó trabajando para mí:
# Never trust parameters from the scary internet, only allow the white list through.
def checkout_params
params.require(:checkout).permit(:job, :shift, :employee_ids, :date, :hours, :sales, :tips, :owed, :collected, :notes)
end
Aquí está la combinación de cambios que funcionó.
- db / schema.rb - https://gist.github.com/leemcalilly/32c792277de335aa54b8
- controladores / checkouts_controller.rb - https://gist.github.com/leemcalilly/6e01ff8b86b1bdd078ed
- controladores / employees_controller.rb - https://gist.github.com/leemcalilly/ad8d9f696b3121fd20e8
- models / checkout.rb - https://gist.github.com/leemcalilly/6ffb28d54c6ea896bac5
- models / employee.rb - https://gist.github.com/leemcalilly/85f53606494743e3d3b1
- models / employment.rb - https://gist.github.com/leemcalilly/b9f9c8b750a23c8f3611
- views / checkouts / _form.html.erb - https://gist.github.com/leemcalilly/d148d00345ad656fcd75
- views / checkouts / index.html.erb - https://gist.github.com/leemcalilly/95f19b23ed121e40f73d
- views / checkouts / show.html.erb - https://gist.github.com/leemcalilly/64ef85f66aa5d887489d
Sin embargo, todavía no entiendo muy bien por qué funcionó.
Puedo publicar la declaración de permiso que uso en uno de mis controladores. Esto tiene una asociación de muchos a muchos también. Anida la matriz de permisos. Use la asociación de búsqueda en su declaración de permiso. La única diferencia debería ser que la tuya no se anidará por tercera vez.
En mi caso, la asociación Quote has_many :quote_items
.
QuoteItems has_many :quote_options, :through => quote_item_quote_options
.
En quotes_controller.rb
params.require(:quote).permit(:quote_date, :good_through, :quote_number, quote_items_attributes: [:id,:quote_id, :item_name, :material_id, quote_item_quote_options_attributes:[:quote_option_id,:quote_item_id,:qty,:_destroy,:id]])
Tenga en cuenta que el nombre que le da a sus parámetros fuertes (empleados, employee_ids, etc.) es en gran medida irrelevante porque depende del nombre que elija enviar. Los parámetros fuertes no funcionan con "magia" en función de las convenciones de nomenclatura.
El motivo por el que gist.github.com/leemcalilly/a71981da605187d46d96 arroja un error de "parámetro no permitido" en ''employee_ids'' es porque está esperando una matriz de valores escalares, por https://github.com/rails/strong_parameters#nested-parameters , no solo un valor escalar.
# If instead of:
... "employee_ids" => "1" ...
# You had:
... "employee_ids" => ["1"]
Entonces sus fuertes parámetros funcionarían, específicamente:
... { :employee_ids => [] } ...
Porque está recibiendo una matriz de valores escalares en lugar de solo un valor escalar.