ActiveSupport::HashWithIndifferentAccess on Embedded Form Update
activesupport, forms, ruby-on-rails
Solution
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 the `player=` method that's normally defined for a `has_one` association. The `player_attributes=` method accepts a hash of attributes, whereas the `player=` 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 calling `fields_for :player`:
`<input name="players_to_team[player_attributes][name]" ... />` When you call `update_attributes` in your controller, the first example will call `player=`, while the second example will call `player_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 to `player=`, only a Player object.
It appears that the only safe way to use `fields_for` with `accepts_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 :-)
Problem
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