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

Tyl*_*itt 8 forms ruby-on-rails 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 %>
Run Code Online (Sandbox Code Playgroud)

楷模:

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
Run Code Online (Sandbox Code Playgroud)

控制器:

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
Run Code Online (Sandbox Code Playgroud)

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

:players_to_team

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

编辑

BT是一个专栏players_to_teams.如果我删除teh field_for块,我可以成功保存BT字段/ players_to_teams行.

谢谢

Tyl*_*itt 6

归功于@Brandan.回答:在fields_for中使用":"和"@"有什么区别

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

在调用accepts_nested_attributes_for之后,您现在在模型上有一个名为player_attributes =的实例方法.这是通常为has_one关联定义的player =方法的补充.player_attributes =方法接受属性的散列,而player =方法只接受实际的Player对象.

以下是调用fields_for @ players_to_teams.player时生成的文本输入示例:

这里是调用fields_for时的相同输入:player:

当您在控制器中调用update_attributes时,第一个示例将调用player =,而第二个示例将调用player_attributes =.在这两种情况下,传递给方法的参数都是哈希(因为params最终只是哈希的哈希).

这就是你获得AssociationTypeMismatch的原因:你不能将哈希传递给player =,只能传递一个Player对象.

看来,将fields_for与accepts_nested_attributes_for一起使用的唯一安全方法是传递关联的名称而不是关联本身.

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