2015-12-29 2 views
1

Я делаю заявку на использование материала. Продукт может быть частью многих сборок и иметь много sub_products. У меня есть следующие модели:Каков наиболее эффективный способ выбора продуктов и суб-продуктов продуктов? Self-Referential has_and_belongs_to_many Association

models/product.rb 
has_many :sub_structure, primary_key: "produktnr", class_name: "Structure", foreign_key: "produktnr" 
has_many :sub_products, through: :sub_structure, source: :product 
has_many :structures, primary_key: "produktnr", class_name: "Structure", foreign_key: "delproduktnr" 
has_many :assemblies, through: :structures, source: :assemblie 

models/structre.rb 
belongs_to :assemblie, primary_key: "produktnr", class_name: "Product", foreign_key: "produktnr" 
belongs_to :product, primary_key: "produktnr", class_name: "Product", foreign_key: "delproduktnr" 

Чтобы выбрать все субпродукты легко:

@product.sub_products 

Но что является наиболее эффективным способом, чтобы выбрать субпродукты и они субпродукты?

Что-то вроде:

@product.sub_products.sub_products 

ответ

0

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

class Product 
    @@all_products = nil 

    def self.all_products 
    @@all_products 
    end 

    #You will have to call this right before getting the children products 
    def self.cache_products 
    if defined? @@all_products && @@all_products.nil? 
     @@all_products = ActiveSupport::Cache::MemoryStore.new(expires_in: 5.minutes) 
     list = Product.all.ordered.pluck(:id, :name, :parent_id) 
     product_instances = [] 
     list.each {|n| 
     p = Product.new 
     p.id = n.first 
     p.name = n.second 
     p.parent_id = n.third 
     product_instances << p 
     } 
     @@all_products.write('products', product_instances) 
    end 
    @@all_products.read('products').select{|c| c.parent_id == nil} 
    end 

    def self.get_children(products) 
    children = [] 
    products.each do |p| 
     children += Product.all_products.read('products').select { |j| p.id == j.parent_id }} 
    end 
    children 
    end 

    def self.products_with_no_children 
    Product.where("id NOT IN (#{Product.all.pluck(:parent_id)})") 
    end 
end 
+0

Я попытался создать метод класса в Product, и он работает. Проблема в том, что этот метод запускает SQL-запрос для каждого субпродукта, что замедляет его. – erlendjohan

+0

Можно ли сделать один запрос для выбора всего субпродукта, у которого нет субпродуктов? – erlendjohan

+0

обновил ответ, опять же, это не очень, но это сработало для меня. – fabriciofreitag

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