Как сгруппировать все объекты в моей модели по столбцу в одной модели, не используя модель соединения? - PullRequest
0 голосов
/ 15 марта 2020

У меня есть модель Position, которая имеет следующую схему:

# Table name: positions
#
#  id                :bigint           not null, primary key
#  action            :integer
#  current_price     :float
#  current_value     :float
#  status            :integer          default("0")
#  ticker            :string
#  volume            :integer
#  created_at        :datetime         not null
#  updated_at        :datetime         not null
#  portfolio_id      :integer
#  stock_id          :integer

  belongs_to :portfolio
  belongs_to :stock

Моя User модель выглядит следующим образом:

  has_one :portfolio, dependent: :destroy
  has_many :positions, through: :portfolio, dependent: :destroy

Моя Portfolio модель выглядит следующим образом this:

class Portfolio < ApplicationRecord
  belongs_to :user
  has_many :positions
end

Что я хотел бы сделать, это вернуть все позиции current_user, все сгруппированные по ticker из position, без необходимости делать join на модель stock в виде массива или некоторого объекта AR, который я могу перебирать и перечислять каждый объект AR в каждой группе.

Способ, которым я смог успешно это сделать, таков:

@positions = current_user.positions.buy.open.order(transaction_date: :desc)
@grouped_stocks = @positions.joins(:stock).group_by { |ps| ps.stock.ticker }

Но, в идеале, я хотел бы сделать это только для первого запроса.

Я попробовал следующее, но все они не работают.

current_user.positions.buy.open.group("ticker")
=> #<Position::ActiveRecord_AssociationRelation:0x3ffdf189d6d4>

current_user.positions.buy.open.order(transaction_date: :desc).group("ticker.name")
      Position Load (2.9ms)  SELECT "positions".* FROM "positions" INNER JOIN "portfolios" ON "positions"."portfolio_id" = "portfolios"."id" WHERE "portfolios"."user_id" = $1 AND "positions"."action" = $2 AND "positions"."status" = $3 GROUP BY ticker.name ORDER BY "positions"."transaction_date" DESC  [["user_id", 2], ["action", 0], ["status", 0]]
  Position Load (2.3ms)  SELECT  "positions".* FROM "positions" INNER JOIN "portfolios" ON "positions"."portfolio_id" = "portfolios"."id" WHERE "portfolios"."user_id" = $1 AND "positions"."action" = $2 AND "positions"."status" = $3 GROUP BY ticker.name ORDER BY "positions"."transaction_date" DESC LIMIT $4  [["user_id", 2], ["action", 0], ["status", 0], ["LIMIT", 11]]
=> #<Position::ActiveRecord_AssociationRelation:0x3ffdefe0a7a4>

Как сделать Я делаю это?

Редактировать

Смотрите пример снимка экрана ниже, как я хочу организовать результаты:

screenshot-of-data-layout

1 Ответ

1 голос
/ 15 марта 2020

Я вижу, у вас есть ticker в таблице позиций, а не в таблице stocks. Так что вам не нужно смотреть на таблицу stocks, если это так. (вероятно, лучше иметь его в таблице запасов), также transaction_date не указан выше, поэтому я предполагаю, что он находится в таблице positions.

Это более или менее то, что вы имели, я предполагаю, что group('ticker.name') не подходит для вас, так как вам нужно сгруппировать по столбцу positions таблицы ticker.

@positions_grouped_by_ticker = current_user.positions.buy.open.group('positions.ticker').order(transaction_date: :desc)

Использование group вернет вам массив массивов, а не коллекцию AR.

# view.html.erb
@grouped_positions.each do |stock_positions|
  <%= render stock_positions %>
end
...