使用嵌套的has_many获取记录数

时间:2017-01-23 18:27:52

标签: ruby-on-rails ruby activerecord

我有一个ID为1的记录A,它有多个B记录,每个记录都有很多C.

  

A(id = 1)=> [b记录] => [[每个b的C记录]]

我需要得到给定A的C计数。

我很确定这与joins,群组, or订单`有关,但我不确切知道是什么。我需要一种在常量SQL操作中执行此操作的方法。没有迭代查询。

4 个答案:

答案 0 :(得分:1)

类似的东西:

A.join(:b => :c).where(id: 1).count("c.id")

如果您已有A的实例:

a.b.joins(:c).count("c.id")

答案 1 :(得分:1)

使用has_many :through association

class A < ActiveRecord::Base
  has_many :bs
  has_many :cs, through: :bs
end

class B < ActiveRecord::Base
  belongs_to :a
  has_many :cs
end

class C < ActiveRecord::Base
  belongs_to :b
end

现在你可以做到:

a.cs.count

如果多次通过a.cs关联是您不会经常使用的,并且您不想将其添加到模型中,那么您可以使用merge代替:

C.joins(:b).merge(a.bs).count

答案 2 :(得分:1)

有几种方式

C.joins(:b).where(:bs => {:a_id => a.id}).count

class A < ActiveRecord::Base

  has_many :bs
  has_many :cs, :through => :bs

end

# Then you can do this, nice and easy to read.  
# Use size, not count in case they are already loaded.

a.cs.size

甚至

  A.where(:id => a.id).joins(:bs => :cs).count

答案 3 :(得分:1)

假设我有理由不通过bs为cs创建多个关联,我会做类似的事情:

class A < ActiveRecord::Base
  has_many :bs
  # has_many :cs, through: :bs - this allows a.cs.size as has been noted here
end

class B < ActiveRecord::Base
  has_many :cs
  belongs_to :a
end

class C < ActiveRecord::Base
  belongs_to :b
end


# you can always do this if you don't want to create the above association through bs:
a.bs.flat_map(&:cs).size