2013-04-02 2 views
1

в моем приложении у меня есть модели товара, категория и категоризации определяется как выше:Rails: применяются, когда условия для обеих моделей и ассоциаций

class Item < ActiveRecord::Base 
     attr_accessible :name, :description, :property_valuations, :barcode 

     has_many :categorizations 
     has_many :categories, :through => :categorizations 
    end 

    class Category < ActiveRecord::Base 
     attr_accessible :name, :description, :parent, :children, :items, :parent_id 

     has_many :children, :class_name => "Category", :foreign_key => "parent_id", :dependent => :nullify 
     belongs_to :parent, :class_name => "Category" 

     has_many :categorizations 
     has_many :items, :through => :categorizations 

     def all_children(children_array = []) 
     children = Category.where(:parent_id => self.id).includes(:items) 

     children_array += children.all 
     children.each do |child|  
      children_array = child.all_children(children_array) 
     end 
     children_array 
     end 

    end 

class Categorization < ActiveRecord::Base 
    attr_accessible :category, :item 

    belongs_to :category 
    belongs_to :item 

end 

Я искать дерево категорий рекурсивно для элементов, связанных с категориями. Однако, помимо фильтрации категорий по parent_id, я хочу применить имя элемента фильтра. Как я могу это сделать (я ожидал чего-то вроде Category.where(:parent_id => self.id).includes(:items).where(:name => 'something...'))?

Заранее благодарен!

ответ

0

Вы можете сделать

Category.where(:parent_id => self.id).includes(:items).where("items.name like ?", '%cheap%') 

Что получит категории, а элементы, которые соответствовали критериям.

т.е.

categories = Category.where(:parent_id => 2).includes(:items).where("items.name like ?", 'AA%') 
categories.first.items.size # -> 2 
categories.first.id # -> 1 
Category.find(1).items.size # -> 3 
Category.find(1).items.where("name like ?", 'AA%').count # -> 2 

Если вы просто хотите, чтобы получить пункты подкатегорий родительской категории:

parent_category = Category.find(2) 
Item.joins(:categories).where(categories: {parent_id: parent_category.id}).where("items.name like ?", 'AA%') 
+0

Разве это не только предметы, связанные с категориями, которые являются прямыми детьми выбранной категории? – elc

+0

Это получает категории, связанные с предметами, которые вы ищете, и когда вы проверяете элементы каждой категории, они получают только те элементы, которые соответствуют критериям. Какой результат вы хотите получить? Его непонятно (по крайней мере для меня) на вопрос. – rorra

+0

Предполагая, что вы хотите проверить все идентификаторы вашего all_children, если вы создадите массив all_children_ids, то вы можете найти (all_children_ids), и это приведет к эффективному «Найти xx в» sql вместо повторяющихся запросов, если вы нажмете идентификатор отдельно. – elc

0

рекурсивных запросов (чтобы избежать ручной рекурсию ваших all_children функция) может поддерживаться вашей базой данных, например postgres с помощью команды with, но у рельсов нет обертки, которая обращается к ней. Если эта рекурсия случается очень часто, стоит прочитать здесь: http://gmarik.info/blog/2012/10/14/recursive-data-structures-with-rails - и действительно, есть некоторые многообещающие камни, затрагивающие эту проблему, но я не использовал их лично.

Смежные вопросы