我有一个多对多,HMT
模型设置,我想添加一个计数值作为tab_community#index
方法的一部分返回。感兴趣的表和连接表的模型如下:
class TabCommunity < ApplicationRecord
belongs_to :ref_community_type
has_many :tab_client_project_communities
has_many :tab_projects, through: :tab_client_project_communities
has_many :tab_community_accounts
has_many :tab_accounts, through: :tab_community_accounts
has_many :tab_client_project_communities
has_many :ref_platforms, through: :tab_client_project_communities
end
class TabCommunityAccount < ApplicationRecord
belongs_to :tab_community
belongs_to :tab_account
end
#index
方法目前看起来像这样:
_tab_community_ids = params[:tab_community_ids].split(',')
@tab_communities = TabCommunity.where(id: _tab_community_ids).includes(:ref_platforms).all.order(:updated_at).reverse_order
此查询是我想在ActiveRecord中复制的内容:
select (select count(*) from tab_community_accounts where tab_community_id = c.id) as cnt, c.* from tab_communities c
我想要的结果如下:
7318 149 sports_writers 7 2017-12-17 15:45:36.946965 2017-12-17 15:45:36.946965
0 172 random_admin 8 2018-04-16 19:21:21.844041 2018-04-16 19:21:21.844041
2731 173 random_aacc 7 2018-04-16 19:22:35.074461 2018-04-16 19:22:35.074461
(第一列为count(*) from tab_community_accounts
,其余列为tab_communities
。)
从我到目前为止所见,我应该使用.select()
或.pluck()
,但两者都不适合我。我试过这个:
TabCommunity.pluck("distinct tab_community_accounts.tab_account_id as cnt").where(id: _tab_community_ids).includes(:ref_platforms).all.order(:updated_at).reverse_order
这接近我需要的还是完全关闭?
答案 0 :(得分:3)
你想要的是:
@tab_communities = TabCommunity
.where(id: _tab_community_ids)
.select('tab_communities.*, count(tab_community_accounts.id) AS cnt')
.left_outer_joins(:tab_community_accounts)
.includes(:ref_platforms) # consider if you actually need this
.group(:id)
.order(updated_at: :desc) # use an explicit order instead!
TabCommunity Load (1.1ms) SELECT tab_communities.*, count(tab_community_accounts.id) AS cnt FROM "tab_communities" LEFT OUTER JOIN "tab_community_accounts" ON "tab_community_accounts"."tab_community_id" = "tab_communities"."id" WHERE "tab_communities"."id" = 1 GROUP BY "tab_communities"."id" ORDER BY "tab_communities"."updated_at" DESC
=> #<ActiveRecord::Relation [#<TabCommunity id: 1, created_at: "2018-05-07 21:13:24", updated_at: "2018-05-07 21:13:24">]>
.select
只是改变了查询的SELECT
部分。返回的结果仍然是包含模型实例的ActiveRecord::Relation
。
ActiveRecord将自动为cnt
创建一个属性:
irb(main):047:0> @tab_communities.map(&:cnt)
=> [1]
另一方面, .pluck
只是拉取列值,如果查询包含多个列,则返回数组或数组数组。
@tab_communities = TabCommunity
.where(id: _tab_community_ids)
.left_outer_joins(:tab_community_accounts)
.includes(:ref_platforms) # consider if you actually need this
.group(:id)
.order(updated_at: :desc)
.pluck('tab_communities.id, count(tab_community_accounts.id) AS cnt')
(1.0ms) SELECT tab_communities.id, count(tab_community_accounts.id) AS cnt FROM "tab_communities" LEFT OUTER JOIN "tab_community_accounts" ON "tab_community_accounts"."tab_community_id" = "tab_communities"."id" WHERE "tab_communities"."id" = 1 GROUP BY "tab_communities"."id" ORDER BY "tab_communities"."updated_at" DESC
=> [[1, 1]]
使用.*
并不是一个好主意,因为你不知道属性在结果数组中的顺序。