在fields_for中使用“:”和“@”有什么区别
我正在我的rails应用程序中设置嵌入式表单。
这不起作用
PlayersToTeams#edit
给我一个ActiveRecord::AssociationTypeMismatch
错误。 注意forms_for
行中的@players_to_teams.player
。
这确实有效:
PlayersToTeams#edit
注意:player
fields_for
行中的:player
调用。
使用符号和使用实例之间的区别是什么? 我想我会想在这种情况下使用一个实例,但我猜不是吗?
编辑
楷模:
class Player < ActiveRecord::Base has_many :players_to_teams has_many :teams, through: :players_to_teams end class PlayersToTeam < ActiveRecord::Base belongs_to :player belongs_to :team accepts_nested_attributes_for :player 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
示例项目
Github: https : //github.com/workmaster2n/embedded-form-errors
看起来fields_for
无法弄清楚@players_to_teams
实例变量的player
关联是什么。 您可以通过明确指定关联的名称(即:player
)来绕过它。 你在两个方向定义关联吗? 即:
class PlayersToTeam < ActiveRecord::Base has_one :player end class Player < ActiveRecord::Base belongs_to :players_to_team end
另外,查看fields_for
的文档 ,第一个参数称为record_name
,因此看起来Rails期望关联的名称而不是关联本身。 但是如果不深入研究代码,很难准确地说出该方法的作用,并且他们的一些示例确实将关联直接传递给fields_for
。
好的,我能够克隆你的示例项目并重现错误。 我想我明白发生了什么。
在调用accepts_nested_attributes_for
,您现在在模型上有一个名为player_attributes=
的实例方法。 这是通常为has_one
关联定义的player=
方法的补充。 player_attributes=
方法接受属性的散列,而player=
方法只接受实际的Player
对象。
以下是调用fields_for @players_to_teams.player
时生成的文本输入fields_for @players_to_teams.player
:
这里是调用fields_for :player
时的相同输入fields_for :player
:
当您在控制器中调用update_attributes
时,第一个示例将调用player=
,而第二个示例将调用player_attributes=
。 在这两种情况下,传递给方法的参数都是哈希(因为params
最终只是哈希的哈希)。
这就是你获得AssociationTypeMismatch
的原因:你不能将哈希传递给player=
,只能传递一个Player
对象。
看来,将fields_for
与accepts_nested_attributes_for
一起使用的唯一安全方法是传递关联的名称而不是关联本身。
所以要回答你原来的问题 ,区别在于一个有效,另一个没有:-)