Leeder Leeder - 1 year ago 103
Ruby Question

Rails doesn't update nested attributes

I create an application, which is basically a character creator for an RPG with interactive and dynamic forms. I use Rails, and I cannot update my form properly. The base model updates well, but all nested don't.

So, I have

class Character < ApplicationRecord
has_many :attr4characters, autosave: true
accepts_nested_attributes_for :attr4characters, allow_destroy: true


class Attr4character < ApplicationRecord
belongs_to :character

which represent a character and a set of his attributes. Each record in Attr4character is a different attribute.

The Show view is simple:

<div class="field">
<%= f.label :description %>
<%= f.text_area :description %>

<div class="field">
<%= f.label :character_type %>
<%= f.select(:character_type, options_for_select(["Zhong Lung", "Shih", "Hsien", "Garou", "Technocrat"])) %>

<% f.object.attr4characters.each do |attr| %>
<%= f.fields_for attr do |attr_f| %>
<div class="field">
<%= attr_f.label "Field name" %>
<%= attr_f.text_field :field_name %>
<div class="field">
<%= attr_f.label "Field value" %>
<%= attr_f.text_field :field_value %>
<% end %>
<% end %>

<div class="actions">
<%= f.submit %>

And finally my characters_controller:

def update
respond_to do |format|
if @character.update(character_params)
format.html { redirect_to @character, notice: 'Character was successfully updated.' }
format.json { render :show, status: :ok, location: @character }
format.html { render :edit }
format.json { render json: @character.errors, status: :unprocessable_entity }

def set_character
@character = Character.find(params[:id])

def character_params
params.require(:character).permit(:id, :name, :player, :description, :character_type, attr4characters_attributes: [:id, :character_id, :field_name, :field_value])

So, I have a form, which correctly display a character and all set of his attributes. When I update a character field (like :description), it is normally updated. When I update any nested field, Rails says that character is successfully updated and nothing changes! I searched with Google, and I found a lot of problems with nested attributes in Rails forms, but none of the recipes worked for me. I even encountered opinions that it is a bug in Rails 4, but I use 5th version...

Please, advice on the topic. Is it a bug really? Or am I doing something wrong? I'm new on Rails, so I don't exclude that possibility. :)

By the way, in the server's log I found that there is warning about attr4characters.

Processing by CharactersController#update as HTML
Parameters: {"utf8"=>"\u2713", "authenticity_token"=>"xeYyIRc13YiOk29v18rFM6Oh5OHRRuPpSKEQuIHE/U4uhANEF7TwMp8mb6hv6L7mUAm5MngAuyFayHcWV/Vvbw==", "character"=>{"name"=>"Ray", "player"=>"111", "description"=>"A Zhong Lung suicider", "character_type"=>"Hsien", "attr4character"=>{"field_name"=>"Gift1", "field_value"=>"Sense Wyrm"}}, "commit"=>"Update Character", "id"=>"3"}
Character Load (0.2ms) SELECT "characters".* FROM "characters" WHERE "characters"."id" = ? LIMIT ? [["id", 3], ["LIMIT", 1]]
Unpermitted parameter: attr4character
(0.1ms) begin transaction
SQL (0.9ms) UPDATE "characters" SET "character_type" = ?, "updated_at" = ? WHERE "characters"."id" = ? [["character_type", "Hsien"], ["updated_at", 2016-09-13 14:39:10 UTC], ["id", 3]]
(24.3ms) commit transaction

But attr4characters are permitted in the characters_controller...

Answer Source

The warning is telling you that it is ignoring all the attr4character attributes. Your permit code is correct as is your model, but your view doesn't match them. You should be doing

f.fields_for :attr4characters do |attr_f|

And let rails handle iterating over the association. This will also ensure that attributes are named correctly (so they will be allowed through by your whitelist)

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download