嵌入式表单更新上的ActiveSupport :: HashWithIndifferentAccess

时间:2012-04-05 01:58:22

标签: ruby-on-rails forms activesupport

当我尝试更新嵌入表单时,我收到ActiveSupport::HashWithIndifferentAccess错误。

这是最简单的例子:

形式:

<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 %>

型号:

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

控制器:

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

这是表单提交时的params[:players_to_team]对象:

:players_to_team

ActiveSupport::HashWithIndifferentAccess错误是什么意思?要让此表单更新players_to_team条目,我需要做什么?

修改

BTplayers_to_teams中的一列。如果我删除了field_for阻止,我可以成功保存BT字段/ players_to_teams行。

由于

1 个答案:

答案 0 :(得分:6)

归功于@Brandan。已回答:What is the difference between using ":" and "@" in fields_for

  

好的,我能够克隆你的示例项目并重现错误。   我想我明白发生了什么。

     

在您调用accepts_nested_attributes_for之后,您现在拥有了   名为player_attributes=的模型上的实例方法。这是在   通常为player=定义的has_one方法的补充   协会。 player_attributes=方法接受哈希值   属性,而player=方法只接受实际的播放器   对象

     

这是您调用时生成的文本输入的示例   fields_for @players_to_teams.player

     

<input name="players_to_team[player][name]" ... />就是这样   调用fields_for :player时的相同输入:

     

<input name="players_to_team[player_attributes][name]" ... />当你   在您的控制器中调用update_attributes,第一个示例将调用   player=,而第二个示例将调用player_attributes=。在   两种情况下,传递给方法的参数都是哈希(因为   params最终只是哈希的散列。)

     

这就是你得到AssociationTypeMismatch的原因:你无法通过   哈希到player=,只是一个Player对象。

     

似乎是使用fields_for的唯一安全方式   accepts_nested_attributes_for是通过传递名称   协会,而不是协会本身。

     

所以回答你原来的问题,区别在于一个人有效   而另一个则没有: - )