是否可以使用具有has_many关系计数的条件?

时间:2012-03-21 14:15:34

标签: ruby-on-rails ruby-on-rails-3 associations conditional-statements

我有一个项目列表,并且只想显示有任务的项目。是否可以使用具有has_many关系计数的条件?

# get my project list
Project.includes(:tasks).where(...)

class Project < ActiveRecord::Base
  has_many :tasks

class Task < ActiveRecord::Base
  belongs_to :project

目前我正在通过循环这样做,但我不认为这是正确的方法。

3 个答案:

答案 0 :(得分:1)

includes指令通常表示只是急于加载这些关联,而不是JOIN它们在数据库方面,所以如果没有一些额外的工作,你就不能真正做到这里的条件。

可以很好地扩展的一种方法是使用关联的counter_cache功能,这样您始终可以获得任务数量的数字计数。您甚至可以在这些上添加索引,以进一步提高查询的性能。

另一种方法是尝试从tasks表向后工作,也许就像:

Project.where('id IN (SELECT DISTINCT project_id FROM tasks)')

据推测,您在project_id表中的tasks上有一个索引,可以使这个操作相当便宜。

答案 1 :(得分:1)

如果问题像标题所暗示的一样简单,那么不确定为什么这不会起作用:

Project.joins(:tasks)

除非另有说明,否则连接将是内连接,因此排除任何项目没有任务的结果,所以也许这就是你需要的所有......如果要显示所有项目有任务。

如果您有某些条件(例如,状态为活动的项目),您还可以指定类似

的条件
Project.joins(:tasks).where("status = 'active')

或者我错过了什么?

答案 2 :(得分:1)

由于您已经急于为项目加载任务,因此您可以使用以下语句来获取包含任务的项目。

# get my project list
Project.includes(:tasks).where("tasks.id IS NOT NULL")

这可行,因为includes使用LEFT OUTER JOIN

另一方面,如果您不想急于加载任务,可以使用joins,因为它使用INNER JOIN。

Project.joins(:tasks).where(...)