I'm working on a form with nested fields, and while I have it working perfectly fine, the docs I consulted while building it have left me slightly confused.
As an example form, (where the user model has accepts_nested_attributes_for :thing
):
<%= form_for @user, url: create_user_path do |f| %>
<%= f.fields_for :thing do |tf| %>
The params recieved will include a hash of thing_attributes
inside the user
params.
So far all good, and aligns with nested_attributes_for documentation. But when consulting the ActionController::Parameters documentation, specifically on permit, it seems like the nested params should be passed in a hash named just "thing" (with no _attributes suffix). The example in the documentation is a Person object, with nested params for Pets:
params = ActionController::Parameters.new({
person: {
name: "Francesco",
age: 22,
pets: [{
name: "Purplish",
category: "dogs"
}]
}
})
permitted = params.permit(person: [ :name, { pets: :name } ])
Consulting other SO answers, it seems that using the _attributes suffix is the normal and expected Rails Way, but there are several questions from people trying to either add the suffix or remove it. Is this just an artifact of building Rails APIs with JSON attributes? Is there any reason why I should expect or use nested params without the _attributes suffix in an all-rails monolith?
Ah, I think I have it figured - it has to do with pluralization of the object in the fields for. So the following would generate nested params without the _attributes suffix. This would be for objects with a has_many relationship instead of a has_one or belongs_to.
<%= form_for @user, url: create_user_path do |f| %>
<%= f.fields_for :things do |tf| %>
Makes more sense now.