Rails:适用于模型和关联的条件

时间:2013-04-02 21:46:12

标签: ruby-on-rails ruby associations where

在我的应用程序中,我有如上定义的模型项目,类别和分类:

    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...'))?

提前致谢!

2 个答案:

答案 0 :(得分: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%')

答案 1 :(得分:0)

您的数据库可能支持递归查询(以避免all_children函数的手动递归),例如通过with命令的postgres,但rails没有访问它的包装器。如果这种递归发生了很多,那么可能值得在这里做一些阅读:http://gmarik.info/blog/2012/10/14/recursive-data-structures-with-rails - 看起来有一些很有希望解决这个问题的宝石,但我并没有亲自使用它们。