使用“:"和“:"有什么区别?和"@"在fields_for [英] What is the difference between using ":" and "@" in fields_for

查看:80
本文介绍了使用“:"和“:"有什么区别?和"@"在fields_for的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在Rails应用程序中设置嵌入式表单.

I am setting up embedded forms in my rails app.

这不起作用

<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错误.注意forms_for行中的@players_to_teams.player.

Gives me a ActiveRecord::AssociationTypeMismatch error. Notice the @players_to_teams.player in the forms_for line.

这确实有效:

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

注意fields_for行中的:player调用.

使用符号和使用实例之间有什么区别?我想我想在这种情况下使用实例,但是我猜不是吗?

Whats the difference between using a symbol and using an instance? I would think I would want to use an instance in this case, but I guess not?

修改

型号:

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不能弄清楚player实例变量的player关联是什么.您可以通过明确指定关联的名称(即:player)来绕过该链接.您是否在两个方向上定义关联?即:

It seems like fields_for can't figure out what the player association is for the @players_to_teams instance variable. You bypass that by explicitly specifying the name of the association (i.e., :player). Are you defining the association in both directions? I.e.:

class PlayersToTeam < ActiveRecord::Base
  has_one :player
end

class Player < ActiveRecord::Base
  belongs_to :players_to_team
end

此外,请查看 fields_for的文档,第一个参数称为record_name,因此Rails似乎期望关联的 name 而不是关联本身.但是,如果不深入研究代码就很难确切地知道该方法的功能,而且它们的某些示例确实确实将关联直接传递给了fields_for.

Additionally, looking at the documentation for fields_for, the first parameter is called record_name, so it seems like Rails is expecting the name of the association rather than the association itself. But it's hard to tell exactly what that method does without looking further into the code, and some of their examples do indeed pass the association directly into fields_for.

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

Okay, I was able to clone your sample project and reproduce the error. I think I understand what's happening.

致电 accepts_nested_attributes_for ,现在您的模型上有一个名为player_attributes=的实例方法.这是通常为has_one关联定义的player=方法的补充. player_attributes=方法接受属性的哈希,而player=方法仅接受实际的Player对象.

After your call to accepts_nested_attributes_for, you now have an instance method on your model named player_attributes=. This is in addition to the player= method that's normally defined for a has_one association. The player_attributes= method accepts a hash of attributes, whereas the player= method only accepts an actual Player object.

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

Here's an example of the text input generated when you called fields_for @players_to_teams.player:

<input name="players_to_team[player][name]" ... />

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

and here's that same input when calling fields_for :player:

<input name="players_to_team[player_attributes][name]" ... />

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

When you call update_attributes in your controller, the first example will call player=, while the second example will call player_attributes=. In both cases, the argument passed to the method is a hash (because params is ultimately just a hash of hashes).

这就是为什么要获取AssociationTypeMismatch的原因:您不能将哈希传递给player=,而只能将Player对象传递给该对象.

That's why you were getting an AssociationTypeMismatch: you can't pass a hash to player=, only a Player object.

看来,将fields_foraccepts_nested_attributes_for结合使用的唯一安全方法是传递关联的名称,而不是关联本身.

It appears that the only safe way to use fields_for with accepts_nested_attributes_for is by passing the name of the association and not the association itself.

所以要回答您的原始问题,不同之处在于一个有效,而另一个无效:-)

So to answer your original question, the difference is that one works and the other doesn't :-)

这篇关于使用“:"和“:"有什么区别?和"@"在fields_for的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆