我有一个包含 TeamSeason
的 Rails 应用程序模型类。这个类有一个 has_one
与 Team
的关联模型类,和一个 has_many
关联到另一个TeamSeason
称为 opponents
.我现在正在尝试编写一个传入 Team
的方法并确定它的任何对手是否与那个 Team
相关联.我写的方法看起来像这样:
def plays?(against_team)
total = opponents.count {|opponent| opponent.team == against_team}
return (total > 0)
end
count
方法应该计算在我指定的 block 中产生真值的数组元素的数量。但是,它似乎总是返回数组的全长。就好像我指定的 block 总是产生一个真值,不管怎样。
我添加了各种 puts
打电话试图找出我的逻辑哪里出了问题。这是我的观察:
当我添加任何
puts
在 count 方法旁边的 block 内调用,我没有看到这些语句的任何输出。似乎该 block 的内容从未被执行当我使用对手数组的
each
插入一个额外的循环时方法和一个 block ,我可以打印我的数组对象的值并确认它们是按我预期的方式计算的。我什至可以puts
opponent.team == against_team
的值并验证我编写的 block 的计算结果为false
有些时候,这是应该的。
我在这里错过了什么?
最佳答案
opponents
不是标准的 ruby 数组 - 它是一个 ActiveRecord 关联代理并且对于某些方法表现不同。 count
将在数据库中查询对手的数量,而您正在通过的方 block 将不会被评估。一个更简单的方法来做你想做的事情是这样的:
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?{...}
关于ruby-on-rails - 无法使用数组的计数方法来处理 block ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14743225/