I'm getting an ActiveSupport::HashWithIndifferentAccess
error when I try to update an embedded form.
Here's the simplest example:
Form:
<h1>PlayersToTeams#edit</h1>
<%= form_for @players_to_teams do |field| %>
<%= field.fields_for @players_to_teams.player do |f| %>
<%= f.label :IsActive %>
<%= f.text_field :IsActive %>
<% end %>
<%= field.label :BT %>
<%= field.text_field :BT %>
<br/>
<%= field.submit "Save", class: 'btn btn-primary' %>
<% end %>
Models:
class PlayersToTeam < ActiveRecord::Base
belongs_to :player
belongs_to :team
accepts_nested_attributes_for :player
end
class Player < ActiveRecord::Base
has_many :players_to_teams
has_many :teams, through: :players_to_teams
end
Controller:
class PlayersToTeamsController < ApplicationController
def edit
@players_to_teams=PlayersToTeam.find(params[:id])
end
def update
@players_to_teams=PlayersToTeam.find(params[:id])
respond_to do |format|
if @players_to_teams.update_attributes(params[:players_to_team])
format.html { redirect_to @players_to_teams, notice: 'Player_to_Team was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: @players_to_teams.errors, status: :unprocessable_entity }
end
end
end
end
This is the params[:players_to_team]
object upon form submission:
What does an ActiveSupport::HashWithIndifferentAccess
error mean? What do I need to do to have this form update the players_to_team
entry?
Edit
BT
is a column in players_to_teams
. If I remove teh field_for
block, I can successfully save the BT
field/the players_to_teams
row.
Thanks
Credit goes to @Brandan. Answered: What is the difference between using ":" and "@" in fields_for
Okay, I was able to clone your sample project and reproduce the error. I think I understand what's happening.
After your call to accepts_nested_attributes_for, you now have an instance method on your model named
player_attributes=
. This is in addition to theplayer=
method that's normally defined for ahas_one
association. Theplayer_attributes=
method accepts a hash of attributes, whereas theplayer=
method only accepts an actual Player object.Here's an example of the text input generated when you called
fields_for @players_to_teams.player
:
<input name="players_to_team[player][name]" ... />
and here's that same input when callingfields_for :player
:
<input name="players_to_team[player_attributes][name]" ... />
When you callupdate_attributes
in your controller, the first example will callplayer=
, while the second example will callplayer_attributes=
. In both cases, the argument passed to the method is a hash (because params is ultimately just a hash of hashes).That's why you were getting an
AssociationTypeMismatch
: you can't pass a hash toplayer=
, only a Player object.It appears that the only safe way to use
fields_for
withaccepts_nested_attributes_for
is by passing the name of the association and not the association itself.So to answer your original question, the difference is that one works and the other doesn't :-)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With