2014-05-05 30 views
1

我在TrainerSportists之间有belongs_to/has_many关系。我通过自己的价值观view试图循环是这样的:ActionView :: Template :: Error(未定义的方法`city'为零:NilClass):

<% @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 
+0

安置自己的产品型号代码。 – Pavan

+0

@Pavan使用Model信息编辑了我的帖子。 – Xeen

+0

“code snippet”所属的'view page'属于哪个? – Pavan

回答

2

你得到undefined method 'city' for nil:NilClass在下面的代码:

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

这意味着有是没有关联到它trainer一个sportists记录。 因此,对于那个特定的体育列表记录s.trainernil,您不能在nil对象上调用city

要确定sportist记录您不具有关联trainer,只需更新如下视图代码:

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

这样,即使你没有相关的trainer记录,错误不会被提出。 在呈现视图中,只需查找sportlist记录,该记录不会显示任何city,这将是没有关联的trainersportlist记录。

至于您在

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

sportlist收到belongs_to的trainer第二个错误undefined method 'trainers',你只有动态方法trainer(注单数)提供,并没有trainers(注复数)。另外,s.trainer会返回单个培训师记录,因此您无法使用each方法对其进行迭代,因为它不是一个集合,而是一条记录。

UPDATE

理想情况下,你不应该允许的sportist记录创建无trainer。 您应该在sportlists表上创建的外键trainer_id上添加index有了这个,你甚至不必使用try方法,你的当前代码就可以正常工作。

+0

我想和@安顿格里戈里耶夫所说的一样。我会建议不要使用try方法,而是使用委托方法。这是Rails的最佳实践之一。 – Addicted

+0

我不明白“委托”如何解决它。 '委托人'将再次被称为'trainer.city',即委托给'教练员'。可能你可以解释。 –

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 
+0

你为什么建议如果条件。 – Addicted

+0

@Addicted,以便它检查相关的培训师是否存在。如果存在,则打印培训师城市值。 – Pavan

+0

我想说明一点,我们不应该不必要地使用条件。 – Addicted

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

这将停止代码抛出零误差

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 %> 
相关问题