Rails使用活动记录复杂查询执行内部联接

时间:2015-12-11 17:14:25

标签: ruby-on-rails activerecord inner-join has-many

我必须执行复杂的活动记录查询。

我有5个模特

卡片型号

class Card < ActiveRecord::Base
  has_many :leads
  has_many :programs, through: :leads
end

领导模型

class Lead < ActiveRecord::Base
  belongs_to :card
  belongs_to :program
end

程序模型

class Program < ActiveRecord::Base
  has_many :leads
  has_many :cards, through: :leads
  belongs_to :school
end

学校模式

class School < ActiveRecord::Base
  has_many :programs
  belongs_to :representative
end

代表模型

class Representative < ActiveRecord::Base
  has_many :schools
end

我想计算每所学校和每位代表的卡数。一个代表有很多学校,一个学校有很多课程,一个课程有很多卡。

我知道我必须进行内部连接但经过一些研究后我没有找到任何精确的说明。谢谢你的帮助。

1 个答案:

答案 0 :(得分:0)

为某些模型添加更多关联应该有所帮助。

<int-ws:outbound-gateway id="someID"
request-channel="clientRequest" reply-channel="clientReply"
uri="some.com" reply-timeout="1000" marshaller="clientMarshaller" 
unmarshaller="clientMarshaller" message-sender="messageSender" >
</int-ws:outbound-gateway>

然后,获得单个学校或代表所拥有的卡片数量的简单方法应该很简单。

class School < ActiveRecord::Base
  # in addition to existing relations
  has_many :leads, through: :programs
  has_many :cards, through: :leads
end

class Representative < ActiveRecord::Base
  # in addition to existing relations
  has_many :programs, through: :schools
  has_many :leads, through: :programs
  has_many :cards, through: :leads
end

如果您要获得唯一卡片的数量,即卡片可能与同一所学校或代表中的多个课程相关联,并且您只想对每个卡片计数一次,那么请使用{{ 1}}。

@school.cards.count
@representative.cards.count

现在,如果您希望获得每个学校和代表所拥有的卡片数量,那有点过于棘手,但仍有可能。

distinct

如果您想要为每个学校或代表提供唯一数量的卡片,只需在相应的查询中将@school.cards.distinct.count @representative.cards.distinct.count 更改为@schools = School.select('schools.*, count(cards.id)') .joins(programs: { leads: :card } ) .group(:id) @reps = Representative.select('representative.*, count(cards.id)') .joins(schools: { programs: { leads: :card } } ) .group(:id)

关于这些解决方案的一些注意事项:

  • 如果学校或代表拥有卡,则不会显示在count(cards.id)count(distinct cards.id)个变量中。为了使它们显示,您需要稍微调整一下查询并使用@schools
  • 您可能甚至不需要@representativesLEFT JOIN模型中与:cards的关联来获取计数;你可以使用School关联。但是,这会使得变得更加困难,这就是为什么我选择了Representative