Rails - 多态自连模型关联

时间:2013-08-21 15:51:38

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

我正在构建一个应用程序以跟踪产品设计,我在使用我的关联时遇到了一些麻烦。基本上我有一个模型(Assembly)需要具有多态关联,但也需要能够属于自己。

为了说明,我有三个模型:产品,装配和零件。

  • 产品可以有多个装配体。
  • 装配体可以有许多零件和装配体。
  • 装配属于产品或装配。
  • 零件属于大会。

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

product.rb

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

assembly.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'命令的参数。

提前致谢!

3 个答案:

答案 0 :(得分:1)

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

在Assembly类中替换

has_many :subassemblies, as: :assemblable

通过

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

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

编辑:解决方案的解释

在指定之前:class_name:

调用.subassemblies方法时,rails会查询假设的子组件&#39;模型类匹配&#39; assemblable_id&#39;该类中的列。但是,&#39;子组件&#39;模型类没有定义(无论如何定义它都没有意义),因此错误。

指定:class_name:

因为班级&#39;组装&#39;指定为:class_name,现在rails知道要查询&#39;程序集&#39;模型类并匹配&#39; assemblable_id&#39;列。

流量演示:

# :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.

答案 1 :(得分:1)

  

has_many:子装配,如::assemblable

     

通过

     

has_many:子组件,如:: assemblable,class_name:'Assembly'

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

在指定之前:class_name:

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

指定: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 :(得分:0)

你可以试试这个

product.rb

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

assembly.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