Based on image above, I do a simple example.
Model: Person
class Person < ApplicationRecord
belongs_to :personable, polymorphic: true
end
Model: Customer
class Customer < ApplicationRecord
has_one :person, as: :personable
accepts_nested_attributes_for :person
end
Controller: customers_controller
def new
@customer = Customer.new
@customer.build_person
end
def create
@customer = Customer.new(customer_params)
@customer.save
redirect_to customers_path
end
private
def customer_params
params.require(:customer).permit(:id, person_attributes: [:id, :name, :personable_type, :personable_id])
end
View
<%= form_with(model: customer) do |form| %>
<%= form.fields_for customer.person do |form_fields| %>
<%= form_fields.label :name %>
<%= form_fields.text_field :name %>
<% end %>
<div>
<%= form.submit %>
</div>
<% end %>
When I run using Rails Console it's okay, according code below.
c = Customer.create()
Person.create(name: "Saulo", personable: c)
But when I run using view and controller, i receive the error below.
Unpermitted parameter: :person. Context: { controller: CustomersController, action: create, request: #<ActionDispatch::Request:0x00007fdad45e3650>, params: {"authenticity_token"=>"[FILTERED]", "customer"=>{"person"=>{"name"=>"Alisson"}}, "commit"=>"Create Customer", "controller"=>"customers", "action"=>"create"} }
I believe that the error its in method customer_params, but i don't found a way to resolve it.
Rails is expecting the person
attributes to be nested under person_attributes
, but the form is sending them under person
instead.
To fix this, ensure that fields_for
is correctly setting up the fields to be nested under person_attributes
in the form:
<%= form_with(model: [customer, customer.build_person]) do |form| %>
<%= form.fields_for :person_attributes, customer.person do |person_form| %>
<%= person_form.label :name %>
<%= person_form.text_field :name %>
<% end %>
<%= form.submit %>
<% end %>
This should generate the correct parameter name (person_attributes
) for the nested attributes.