ruby-on-rails - 在 fields_for 中使用 ":"和 "@"有什么区别

标签 ruby-on-rails forms

我正在我的 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.playerforms_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/

相关文章:

ruby-on-rails - 解析从 Rails 表单发送的 ruby​​ 对象

ruby-on-rails - 如果 NOT nil 获取 ActiveRecords

ruby-on-rails - 带时区的 DateTime.new (Rails)

ruby-on-rails - Rails ActiveAdmin索引格式编号

php - 使用 JQuery 重定向到 PHP 页面不传输表单内容

javascript - jQuery的POST触发 "done"但没有数据提交

ruby-on-rails - 取消 Ruby on Rails 中的当前/事件查询

ruby-on-rails - Ruby on Rails - 数组中的 Validates_inclusion_of

python - CherryPy 将查询字符串值与 POST 正文中的表单值结合起来

提交表单后 JQuery 重定向