我正在我的 rails 应用程序中设置嵌入式表单。
这不起作用
<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 %>
给我一个
ActiveRecord::AssociationTypeMismatch
错误。注意 @players_to_teams.player
在 forms_for
线。这确实有效:
<h1>PlayersToTeams#edit</h1>
<%= form_for @players_to_teams do |field| %>
<%= field.fields_for :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 %>
注意
:player
调用fields_for
线。使用符号和使用实例有什么区别?我想我会想在这种情况下使用一个实例,但我猜不是?
编辑
楷模:
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
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
示例项目
Github:https://github.com/workmaster2n/embedded-form-errors
最佳答案
好像是 fields_for
无法弄清楚 player
是什么关联适用于 @players_to_teams
实例变量。您可以通过显式指定关联的名称来绕过它(即 :player
)。您是否在两个方向上定义关联? IE。:
class PlayersToTeam < ActiveRecord::Base
has_one :player
end
class Player < ActiveRecord::Base
belongs_to :players_to_team
end
此外,查看 the documentation for
fields_for
,第一个参数叫做record_name
,所以看起来 Rails 期待的是关联的名称,而不是关联本身。但是如果不进一步查看代码,很难准确地判断该方法的作用,并且他们的一些示例确实将关联直接传递到 fields_for
.好的,我能够克隆您的示例项目并重现错误。我想我明白发生了什么。
在您调用
accepts_nested_attributes_for
之后,现在您的模型上有一个名为 player_attributes=
的实例方法.这是 player=
的补充通常为 has_one
定义的方法协会。 player_attributes=
方法接受属性的散列,而 player=
方法只接受一个实际的 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
在您的 Controller 中,第一个示例将调用 player=
,而第二个示例将调用 player_attributes=
.在这两种情况下,传递给方法的参数都是散列(因为 params
最终只是散列的散列)。这就是为什么你得到一个
AssociationTypeMismatch
: 你不能将哈希传递给 player=
, 只有一个 Player
目的。看来,使用
fields_for
的唯一安全方法与 accepts_nested_attributes_for
是通过关联的名称而不是关联本身。所以回答你原来的问题 ,区别在于一个有效,另一个无效:-)
关于ruby-on-rails - 在 fields_for 中使用 ":"和 "@"有什么区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10021980/