ruby-on-rails - 无法使用数组的计数方法来处理 block

标签 ruby-on-rails ruby ruby-on-rails-3

我有一个包含 TeamSeason 的 Rails 应用程序模型类。这个类有一个 has_oneTeam 的关联模型类,和一个 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/

相关文章:

ruby-on-rails - rspec 国际化测试 View ?

ruby - 在 Ruby + TinyTDS 中参数化 SQL 查询

ruby-on-rails - 重定向到另一个 Controller 中的 SHOW 操作

ruby-on-rails - 纯 HTML 和 Rails/ERB 帮助程序模板之间的性能差异

ruby-on-rails - 带有 bb-code 的 Rails 评论系统

css - 在 Rails 3.1 中调用样式表

ruby-on-rails - rails 3 : How to add a method to the Gem model without changing the Gem source

ruby-on-rails - 如何在 Rails 4 应用程序中启用 CORS

jquery - 带有 Bourbon/Neat 的多列流动文本

ruby - 用 ruby​​ 发送 POST?