Rails 4: модельные отношения и индексация для двух has_many через модели - PullRequest
0 голосов
/ 11 мая 2018

Мой сценарий выглядит следующим образом

Компания has_many покупает как полиморфные отношения

Пользователь has_many покупает как полиморфные отношения

Примечание: между пользователями и компаниями нет никаких отношений

Покупка относится к полиморфизму

Покупка has_many предметов

Пользователь has_many предметов посредством покупок

Код мудрый

class User
  has_many :purchases, as: :purchasable, dependent: :destroy 
  has_many :items, through: :purchases
end

class Purchase
  belongs_to :purchasable, polymorphic: true
  has_many :items, dependent: :destroy
end

class Item
  belongs_to :purchase
end

Вопрос 1: Чтоподходит ли индексирование для User.first.items?

Вопрос 2: Я хочу найти самые последние приобретенные товары, сгруппировав их по категориям товаров.Какова наиболее эффективная индексация / arel / sql для этого?Текущий, и я уверен, что неэффективный, код для этого выглядит следующим образом

class User  
  def most_recent_items
    item_ids = Item.select("MAX(id) AS id").group(:category, :puchase_id).collect(&:id) & items.collect(&:id)
    Item.order("created_at DESC").where(:id => item_ids)
  end
end

1 Ответ

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

Что касается вашего первого вопроса, я не уверен, что понимаю, что вы подразумеваете под «соответствующей индексацией» - но если вы имеете в виду, что вызов user.items не работает для вас, я думаю, что самым простым решением было бы создатьметод класса в User.rb.

def items
  purchases.map(&:items).flatten
end

Что касается второго, есть несколько способов заказать ваши предметы.Если ваши результаты представляют собой коллекцию ActiveRecord, вы можете использовать order так же, как в своем примере.Если результаты представляют собой массив, я бы рекомендовал использовать метод sort_by.

def most_recent_items
  self.items.sort_by(&:created_at)
end

Обратите внимание, что если сортировка таким образом не приводит ваши элементы в нужном порядке, вы можете просто добавить .reverse до конца.Надеюсь, это поможет!

...