使用ActiveRecord(Ruby)如何构建一个全“使用中”的查询?

时间:2012-09-01 05:50:00

标签: sql ruby activerecord join count

我有一个Tag类,它通过has_and_belongs_to_many与一堆其他类相关联,我正在寻找一种简单的方法来只返回“正在使用”的标签集合。

我正在尝试使用scope,如下所示

class Tag < ActiveRecord::Base

  validates_presence_of :name
  validates_uniqueness_of :name

  has_and_belongs_to_many :users
  has_and_belongs_to_many :widgets

  # it's in_use if users.count > 0 || widgets.count > 0
  scope :in_use, joins(:users).where('users.count > 0').merge(joins(:widgets).where("widgets.count > 0"))
end

但是我收到此错误 - SQLException: no such column: users.count

如何最好地达到我想要的效果,以便我可以通过Tag.in_use获取所有正在使用的标签?

2 个答案:

答案 0 :(得分:1)

我不知道用activerecord助手做这件事的方法。但是你可以用raw sql做到这一点。如果您的联接表名为tags_userstags_widgets,那么类似的内容将起作用:

scope :in_use, find_by_sql('select * from tags 
    inner join tags_users on tags.id = tags_users.tag_id 
    inner join users on tags_users.user_id = users.id 
    union select * from tags 
    inner join tags_widgets on tags.id = tags_widgets.tag_id 
    inner join widgets on tags_widgets.widget_id = widgets.id')

答案 1 :(得分:0)

我最终解决了这个问题。

class Tag < ActiveRecord::Base

  validates_presence_of :name
  validates_uniqueness_of :name

  has_and_belongs_to_many :users
  has_and_belongs_to_many :widgets

  def self.in_use
    return find_by_sql('select tags.* from tags 
      inner join tags_users on tags.id = tags_users.tag_id 
      inner join users on tags_users.user_id = users.id 
      union select tags.* from tags 
      inner join tags_widgets on tags.id = tags_widgets.tag_id 
      inner join widgets on tags_widgets.widget_id = widgets.id')
  end

end

find_by_sql子句放入命名的scope实际上并不起作用(请参阅Gordon Wilson答案的评论)。