【问题标题】:What's the most efficient way to select a products sub products and sub sub products? Self-Referential has_and_belongs_to_many Association选择产品子产品和子子产品的最有效方法是什么?自指 has_and_belongs_to_many 关联
【发布时间】:2015-12-29 11:56:30
【问题描述】:

我正在制作物料清单申请。 一个产品可以是许多组件的一部分,并且有许多 sub_products。 我有以下型号:

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

【问题讨论】:

    标签: ruby-on-rails ruby self-reference


    【解决方案1】:

    我肯定知道有更好更合适的方法,但我前几天遇到了同样的问题,我知道这不漂亮,我必须适应你的情况,我没有测试,但你去:

    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
    

    【讨论】:

    • 我尝试在 Product 中创建一个类方法,它可以工作。问题是这种方法会触发每个子产品的 SQL 查询,这使得它变慢了。
    • 是否可以通过一次查询来选择所有没有子产品的子产品?
    • 更新了答案,再次,它并不漂亮,但它对我有用。
    猜你喜欢
    • 1970-01-01
    • 2015-02-19
    • 2011-02-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-26
    相关资源
    最近更新 更多