ActionView :: Template :: Error(未定义的方法`city'代表nil:NilClass):

时间:2014-05-05 18:54:47

标签: ruby-on-rails ruby associations has-many belongs-to

我在belongs_tohas_many之间有Trainer / Sportists个关系。我正试图在view中循环显示它们的值:

<% @sportists.each do |s| %>
 <%= s.name %> <%= s.surname %>
 <%= s.trainer.city %>
<% end %>

Sportist相关信息正常,但trainers - 却没有。我收到标题中给出的错误。如果我在rails console中尝试这样做,一切正常,那么关系应该设置得很好。

我尝试过的事情:

<% s.trainers.each do |t| %>
  <%= t.city %>
<% end %>

这给了我undefined method 'trainers'错误,如果我尝试s.trainer,我会得到

#<TRAINER:0X00000004CE7CB0>

那可能是什么修复?

修改

我的模特:

has_many :sportists
belongs_to :team
accepts_nested_attributes_for :sportists, :reject_if => :all_blank, :allow_destroy => true

Sportist

belongs_to :trainer

控制器

@sportists = Sportist.all

4 个答案:

答案 0 :(得分:2)

您在以下代码中收到undefined method 'city' for nil:NilClass

<% @sportists.each do |s| %>
 <%= s.name %> <%= s.surname %>
 <%= s.trainer.city %>
<% end %>

表示有sportists条记录与trainer没有关联。 因此,对于该特定体育列表记录s.trainernil,您无法在city对象上调用nil

要识别您没有关联sportist的{​​{1}}记录,只需更新以下视图代码:

trainer

这种方式即使您没有关联的<% @sportists.each do |s| %> <%= s.name %> <%= s.surname %> <%= s.trainer.try(:city) %> <% end %> 记录,也不会引发错误。 在渲染视图中,只需查找未显示任何trainer的{​​{1}}记录,即没有关联sportlist的{​​{1}}记录。

至于您在

上收到的第二个错误city
sportlist

sportlist belongs_to trainer,您只能使用动态方法undefined method 'trainers'(注意单数),而不是<% s.trainers.each do |t| %> <%= t.city %> <% end %> (注意复数)。此外,trainer将返回单个教练记录,因此您无法使用trainer方法对其进行迭代,因为它不是一个集合但只有一条记录。

<强>更新

理想情况下,您不应该在没有trainers的情况下创建s.trainer条记录。 您应该在each表上创建的外键sportist上添加trainer有了这个,您甚至不必使用index方法,而且您当前的代码可以正常工作。

答案 1 :(得分:2)

您可以使用委托并避免使用try, if and terniary operator

Sportist

belongs_to :trainer

delegate :city,  to: :trainer, :allow_nil => true

您需要对现有代码进行细微更改,它才能顺利运行:)

<% @sportists.each do |s| %>
  <%= s.name %> <%= s.surname %>
   <%= s.city %>
<% end %>

答案 2 :(得分:0)

好像你的sportists没有trainer。为避免这种情况,请设置if这样的条件。

<% @sportists.each do |s| %>
 <%= s.name %> <%= s.surname %>
 <%= s.trainer.city if s.trianer.present?%>
<% end %>

并且在 Sportist 模型中设置验证应解决空trainer_id

Class Sportist < ActiveRecord::Base

belongs_to :trainer

validates :trainer_id, presence: true

end

答案 3 :(得分:0)

您可以更新代码

   <% @sportists.each do |s| %>
     <%= s.name %> <%= s.surname %>
     <%= s.trainer.city %>
   <% end %>

   <% @sportists.each do |s| %>
     <%= s.name %> <%= s.surname %>
     <%= s.trainer.present? ? s.trainer.city : "No City Found"  %>
   <% end %>

这将停止代码抛出nil错误