简体   繁体   English

Rails-多态自联接模型关联

[英]Rails - Polymorphic Self-Join Model Associations

I'm working on building an app to keep track of product designs, and I'm having some trouble with my associations. 我正在开发一个应用程序以跟踪产品设计,但是我的关联遇到了一些麻烦。 Basically I have a model (Assembly) which needs to have polymorphic association, but also needs to be able to belong to itself. 基本上,我有一个模型(装配体),该模型需要具有多态关联,但是还需要能够属于自己。

To illustrate, I have three models: Product, Assembly, and Part. 为说明起见,我有三个模型:产品,装配体和零件。

  • A Product can have many Assemblies. 一个产品可以有多个程序集。
  • An Assembly can have many Parts AND Assemblies. 装配体可以具有许多零件和装配体。
  • An Assembly belongs to a Product OR an Assembly. 装配体属于产品或装配体。
  • A Part belongs to an Assembly. 零件属于装配体。

My model definitions are currently like this: 我的模型定义当前如下:

product.rb product.rb

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

assembly.rb assembly.rb

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

part.rb part.rb

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

What I would like to be able to do is, given an assembly called "top_assy": 我想要做的是给定一个名为“ top_assy”的程序集:

top_assy.subassemblies.create

However, when I try this, I get the following error: 但是,当我尝试此操作时,出现以下错误:

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

I'm clearly doing something wrong here - what am I missing? 我显然在这里做错了-我想念什么? I have already tried adding 'class_name: "Assembly"' as an argument to the 'has_many :subassemblies' command. 我已经尝试将'class_name:“ Assembly”'添加为'has_many:subassemblies'命令的参数。

Thanks in advance! 提前致谢!

I don't know why this works, but I had the same problem and solve as it: 我不知道为什么会这样,但是我遇到了同样的问题并解决了:

In Assembly class replace 在组装类中替换

has_many :subassemblies, as: :assemblable

by 通过

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

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

Edit: explanation of solution 编辑:解决方案的说明

Before specifying :class_name: 在指定:class_name之前:

When calling .subassemblies method, rails queries a supposed 'Subassembly' model class to match the 'assemblable_id' column in that class. 当调用.subassemblies方法时,rails查询一个假定的'Subassembly'模型类,以匹配该类中的'assemblable_id'列。 However, 'Subassembly' model class is not defined (it doesn't make sense to define it anyway) here and hence the error. 但是,此处未定义“子装配”模型类(无论如何都没有定义),因此会出现错误。

After specifying :class_name: 指定:class_name之后:

Because the class 'Assembly' was specified as :class_name, now rails knows it is to query the 'Assembly' model class and match the 'assemblable_id' column. 因为类“ Assembly”被指定为:class_name,所以Rails知道要查询“ Assembly”模型类并匹配“ assemblable_id”列。

Demonstation of flow: 流量演示:

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

has_many :subassemblies, as: :assemblable has_many:子组件,如::assemblable

by 通过

has_many :subassemblies, as: :assemblable, class_name: 'Assembly' has_many:子组件,如::assemblable,类名:“ Assembly”

Carlos's solution works because now rails knows which class to query, as follows: 卡洛斯的解决方案之所以有效,是因为现在Rails知道要查询哪个类,如下所示:

Before specifying :class_name: 在指定:class_name之前:

When calling .subassemblies method, rails queries a supposed 'Subassembly' model class to match the 'assemblable_id' column in that class. 当调用.subassemblies方法时,rails查询一个假定的'Subassembly'模型类,以匹配该类中的'assemblable_id'列。 However, 'Subassembly' model class is not defined (it doesn't make sense to define it anyway) here and hence the error. 但是,此处未定义“子装配”模型类(无论如何都没有定义),因此会出现错误。

After specifying :class_name: 指定:class_name之后:

Because the class 'Assembly' was specified as :class_name, now rails knows it is to query the 'Assembly' model class and match the 'assemblable_id' column. 因为类“ Assembly”被指定为:class_name,所以Rails知道要查询“ Assembly”模型类并匹配“ assemblable_id”列。

Demonstation of flow: 流量演示:

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

you can try this 你可以试试这个

product.rb product.rb

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

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

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

and now you can referer 现在你可以参考

top_assembley.sub_assemblies.create top_assembley.sub_assemblies.create

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM