【问题标题】:Rails - Polymorphic Self-Join Model AssociationsRails - 多态自联接模型关联
【发布时间】:2013-08-21 15:51:37
【问题描述】:

我正在开发一个应用程序来跟踪产品设计,但我的关联遇到了一些问题。基本上我有一个模型(Assembly),它需要具有多态关联,但也需要能够属于自己。

为了说明,我有三个模型:Product、Assembly 和 Part。

  • 一个产品可以有多个程序集。
  • 一个程序集可以有多个零件和程序集。
  • 程序集属于产品或程序集。
  • 零件属于装配体。

我的模型定义目前是这样的:

产品.rb

class Product < ActiveRecord::Base
  belongs_to :product_family
  has_many :assemblies, as: :assemblable
end

程序集.rb

class Assembly < ActiveRecord::Base
  belongs_to :assemblable, polymorphic: true
  has_many :parts
  has_many :subassemblies, as: :assemblable
end

part.rb

class Part < ActiveRecord::Base
  belongs_to :assembly
  belongs_to :product_family
end   

我想做的是,给定一个名为“top_assy”的程序集:

top_assy.subassemblies.create

但是,当我尝试这个时,我收到以下错误:

NameError: 未初始化的常量 Assembly::Subassembly

我显然在这里做错了什么 - 我错过了什么?我已经尝试将 'class_name: "Assembly"' 作为参数添加到 'has_many :subassemblies' 命令中。

提前致谢!

【问题讨论】:

  • 我认为基本上我需要的是能够生成“多态连接表”的东西。所以它基本上是一个包含三列的连接表:“parent_type”、“parent_id”和“assembly_id”。然后,“parent_type”可以是“Product”或“Assembly”。

标签: ruby-on-rails activerecord polymorphic-associations self-join


【解决方案1】:

has_many :subassemblies, as: :assemblable

通过

has_many :subassemblies, as: :assemblable, class_name: 'Assembly'

Carlos 的解决方案有效,因为现在 rails 知道要查询哪个类,如下所示:

在指定 :class_name: 之前

调用 .subassemblies 方法时,rails 会查询假定的“子组件”模型类以匹配该类中的“assemblable_id”列。但是,此处未定义“子装配”模型类(无论如何定义它没有意义),因此出现错误。

指定:class_name:后

因为类 'Assembly' 被指定为 :class_name,现在 rails 知道它是查询 'Assembly' 模型类并匹配 'assemblable_id' 列。

流程演示:

# :class_name has been specified to be 'Assembly'
ex_asm = Assembly.new # an example assembly
ex_asm.subassemblies # flow:
    # 1. Rails checks the :subassemblies association
    # 2.a. There it is specified to query the class 'Assembly'
    # 2.b. and it is to match the "id" column of ex_asm
    # 2.c. with the 'assemblable_id' column of the Assembly table
    # 3 Rails returns the assemblies matching criteria (2) as
    #   :subassemblies of ex_asm.

【讨论】:

    【解决方案2】:

    我不知道为什么会这样,但我遇到了同样的问题并解决了它:

    在Assembly类替换

    has_many :subassemblies, as: :assemblable
    

    通过

    has_many :subassemblies, as: :assemblable, class_name: 'Assembly'
    

    ================================================ =======================

    编辑:解决方案说明

    在指定:class_name:之前

    调用 .subassemblies 方法时,rails 会查询假定的“子组件”模型类以匹配该类中的“assemblable_id”列。但是,此处未定义“子组件”模型类(无论如何定义它没有意义),因此出现错误。

    指定 :class_name: 后

    因为类 'Assembly' 被指定为 :class_name,现在 rails 知道它是查询 'Assembly' 模型类并匹配 'assemblable_id' 列。

    流程演示:

    # :class_name has been specified to be 'Assembly'
    ex_asm = Assembly.new # an example assembly
    ex_asm.subassemblies # flow:
        # 1. Rails checks the :subassemblies association
        # 2.a. There it is specified to query the class 'Assembly'
        # 2.b. and it is to match the "id" column of ex_asm
        # 2.c. with the 'assemblable_id' column of the Assembly table
        # 3 Rails returns the assemblies matching criteria (2) as
        #   :subassemblies of ex_asm.
    

    【讨论】:

      【解决方案3】:

      你可以试试这个

      产品.rb

      class Product < ActiveRecord::Base
        belongs_to :product_family
        has_many :assemblies
      end
      

      程序集.rb

      class Assembly < ActiveRecord::Base
        attr_accessible :top_assembly_id
        has_many :sub_assemblies, :class_name => "Assembly", :foreign_key => "top_assembly_id"
        belongs_to :top_assembley, :class_name => "Assembly"
        has_many :parts
      end
      

      part.rb

      class Part < ActiveRecord::Base
        belongs_to :assembly
        belongs_to :product_family
      end  
      

      现在你可以引用了

      top_assembley.sub_assemblies.create

      【讨论】:

      • 不幸的是,我使用的是 Rails 4.0.0,所以 attr_accessible 在我的应用程序中不起作用。我在这方面还是新手,还没有完全理解强大的参数——知道如何为 Rails 4 修改它吗?
      • kk 我的意思是你应该在你的装配模型中有一个名为 top_assembly_id 的属性
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-30
      • 2018-01-05
      • 1970-01-01
      • 2018-10-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多