我有一个包含TeamSeason
模型类的Rails应用程序。此类与has_one
模型类具有Team
关联,与另一个名为has_many
的{{1}}具有TeamSeason
关联。我现在正在尝试编写一个传递opponents
的方法,并确定其任何对手是否与Team
相关联。我写的方法看起来像这样:
Team
def plays?(against_team)
total = opponents.count {|opponent| opponent.team == against_team}
return (total > 0)
end
方法应该计算使用我指定的块产生true值的数组元素的数量。但是,它似乎总是返回数组的全长。这就好像我指定的块总是产生一个真值,无论如何。
我添加了各种count
调用来尝试找出我的逻辑出错的地方。这是我的观察:
当我在count方法旁边的块中添加任何puts
调用时,我看不到这些语句的任何输出。看来该块的内容永远不会被执行
当我使用对手数组的puts
方法和一个块插入一个额外的循环时,我可以打印我的数组对象的值并确认它们是按照我的预期进行评估。我甚至可以each
puts
的值,并验证我写的块在某些时候评估为opponent.team == against_team
。
我在这里缺少什么?
答案 0 :(得分:3)
opponents
不是标准的ruby数组 - 它是一个ActiveRecord关联代理,对某些方法的行为也不同。 count
将向数据库查询对手的数量,并且不会评估您传递的块。做你想做的更简单的方法是这样的:
def plays?(against_team)
opponents.joins(:team).where(teams: {id: against_team.id}).exists?
end
这将询问数据库你想要什么,并且当你只检查特定的匹配时避免加载所有对手。或者,您可以加载整个对手列表并使用any?
:
def plays?(against_team)
opponents.any?{|opponent| opponent.team == against_team.id}
end
请注意,这不仅会加载所有对手,而且会一次加载一个对手的球队 - 导致N + 1查询(导致性能问题)。您可以使用includes()
opponents.includes(:team).any?{...}
答案 1 :(得分:0)
您正在尝试的功能可以使用include?
方法实现。
尝试:
def plays?(against_team)
opponents.collect(&:team).include?(against_team)
end