Получить счет из другой таблицы - PullRequest
0 голосов
/ 07 мая 2018

У меня есть модель "многие-ко-многим" 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

(1-й столбец 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

Это близко к тому, что мне нужно, или я полностью выключен?

1 Ответ

0 голосов
/ 08 мая 2018

То, что вы хотите, это что-то вроде:

@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]]

Использование .* с pluck не очень хорошая идея, поскольку вы не знаете, в каком порядке располагаются атрибуты в результирующем массиве.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...