Вопрос по ruby-on-rails – Поиск записей с двумя конкретными записями в другой таблице

6

у меня естьProduct модель, котораяhas_and_belongs_to_many :taxonsи я хочу найти все продукты, которые находятся в конкретных таксонах.

Например, если продукт принадлежит как «Ruby on Rails» и "Рубашки" Таксон, я хочу, чтобы этот продукт был возвращен в наборе данных, ноnot если он принадлежит только одному из "Ruby on Rails" или "Рубашки"

Ваш Ответ

3   ответа
1

Этот ответ от @samuel - именно то, что я искал, но я хотел, чтобы все еще можно было вводить ключевые слова для поиска при фильтрации по Taxon1, Taxon2 и TaxonN. Мне больше не нужно выполнять поиск Taxon1 ИЛИ Taxon2, поэтому я выполнил следующие настройки. Там может быть менее хакерский способ сделать это, но он прекрасно работает для меня.

Я добавил новую область продукта в /app/models/spree/product_decorator.rb

Spree::Product.class_eval do
    add_search_scope :in_all_taxons do |*taxons|
        taxons = get_taxons(taxons)
        id = arel_table[:id]
        joins(:taxons).where(spree_taxons: { id: taxons }).group(id).having(id.count.eq(taxons.size))
    end
end

Затем использовал новую область, добавив ее в /app/models/spree/base_decorator.rb

Spree::Core::Search::Base.class_eval do
    def get_base_scope
        base_scope = Spree::Product.active
        base_scope = base_scope.in_all_taxons(taxon) unless taxon.blank?
        base_scope = get_products_conditions_for(base_scope, keywords)
        base_scope = add_search_scopes(base_scope)
        base_scope
    end
end

Теперь я могу использовать стандартный помощник по поиску для поиска товаров (что означает, что я все еще могу указывать ключевые слова и т. Д. Вместе с несколькими таксонами):

# taxon_ids is an array of taxon ids
@searcher = build_searcher(params.merge(:taxon => taxon_ids))
@products = @searcher.retrieve_products

Это работает для меня и чувствовал себя довольно безболезненно. Однако я открыт для лучших вариантов.

0

Предполагая, что производительность не является обязательным:

a = Taxon.find_by_name!('Ruby on Rails').products.pluck(:id)
b = Taxon.find_by_name!('Shirts').products.where(:id => a)
13

У меня была эта проблема некоторое время назад, к счастью, есть хорошее решение.

def self.has_taxons(taxons)
  id = arel_table[:id]
  Product.joins(:taxons).where(taxons: { name: taxons }).group(id).having(id.count.eq(taxons.size))
end
@RyanBigg Также взгляните на этот камень:github.com/ernie/squeel, Он добавляет слой абстракции над ARel. Это позволяет создавать более сжатые / читабельные запросы. Даже в то время какtaxons.name.in taxons или жеtaxons.name >> taxons это не намного лучше, чем вложенные хэши, вы оцените эту цепочку, если вам когда-либо понадобится более 2 уровней объединения. И вы можете сделать свойhaving вещи без звонкаarel_table, лайк:having{count(id) == some_size}.
Один интернет для вас, сэр. Ryan Bigg

Похожие вопросы