Rails использует метод Model в групповом запросе - PullRequest
2 голосов
/ 24 марта 2019

Я использую has_ancentry драгоценный камень, и я хочу, чтобы количество категорий было в этом формате

"Технология / Ноутбук (50)"

где «Технология» - родительская категория. «Ноутбук» - это дочерняя категория, а «50» - это счет моего сгруппированного запроса

categories = Category.joins(:products)
                         .where(products: {id: @products})
                         .group(:id, :name)
                         .count

Проблема в том, что таким образом я получаю только «ID» дочерней категории. Если я хочу получить «родительскую» категорию, у меня должен быть объект активной записи (потому что в has_ancestry .parent () является объектом метода, а не столбцом базы данных)

Модель

class Category < ApplicationRecord
  has_ancestry
  has_many :products, dependent: :destroy

Категории

 create_table "categories", force: :cascade do |t|
        t.string "name"
        t.datetime "created_at", null: false
        t.datetime "updated_at", null: false
        t.string "ancestry"
        t.index ["ancestry"], name: "index_categories_on_ancestry"
      end

1 Ответ

0 голосов
/ 28 марта 2019

Я немного сбиваю с толку, чтобы понять проблему.

Но у меня есть некоторые решения.

гем предков не поддерживает интерфейс запросов для ассоциации

ТакЯ использую

грязным способом: это вызывает n + 1 проблему запроса

Category.joins(:products).where(products: {id: @products}).group(:id, :name).count
        .map { |k, v| "#{Category.find(k.first).parent.name} / #{k.last} (#{v})" }

коротким путем: это вызывает n + 1 проблему запроса

Product.group(:category).size.map { |k, v| "#{k.parent.name} / #{k.name} (#{v})" }

short way2: этовызывает n + 1 проблему запроса

Category.includes(:products).map { |c| [c.parent&.name, c.name, c.products.size]}

Я хочу использовать необработанный запрос, но в настоящее время я не мог придумать хороший sql, извините,

обновить новый:

products = Product.group(:category).size
categories = Category.where(id: products.map(&:first).map(&:ancestry).uniq).pluck(:id, :name)
result = products.map { |child_category, total| "#{(categories.select { |c| c.first == child_category.ancestry.to_i }.map(&:last)).first} / #{child_category.name} (#{total})" }

Это выглядит несколько сложнее, но имеет только два запроса.

Требуется больше вычислительной мощности на вашем компьютере.

...