我可以在has-and-belongs-to-many-many关系中访问活动记录关联上的调用对象吗?

时间:2018-03-25 13:53:09

标签: ruby-on-rails ruby activerecord associations rails-activerecord

如果我们有这样的has_and_belongs_to_many关系:

class Assembly < ApplicationRecord
  has_and_belongs_to_many :parts
end

class Part < ApplicationRecord
  has_and_belongs_to_many :assemblies
end

我们使用关联来查找属于Assembly id 1 Assembly.find(1).parts 的部分,如下所示:

Assembly

那么有没有办法引用调用关联对象的对象 - 在这种情况下,是一种从Part引用特定Assembly.find(1).parts.each do |part| the_calling_assembly = part.assembly_that_referenced_me() end 的方法?像这样:

The latest released version of Hive as of now is 2.1.x and it does not support Spark 2.x

并且,有没有内置的方法来做这个,有关如何创建这种行为的任何建议?

2 个答案:

答案 0 :(得分:0)

实现此目的的最佳方法是使用连接表的连接模型来实现多对多关系。

所以,现在应该有一个表assemblies_parts

你应该写一个模型:

#assemblies_part.rb

class AssemblyPart < ApplicationRecord
    belongs_to :assembly
    belongs_to :part
end

你也应该改变你的其他模型

class Assembly < ApplicationRecord
    has_many :assembly_parts
    has_many :parts, through: :assembly_parts
end

class Part < ApplicationRecord
    has_many :assembly_parts
    has_many :assemblies, through: :assembly_parts
end

所以,你现在可以做;

Assembly.find(1).assembly_parts.each do |assembly_part|
     assembly = assembly_part.assembly
     part = assembly_part.part
end

如果您希望将装配体保留在零件中,在整个过程中,您可以执行以下操作(注意:这不会持久存储到DB中)

class Part < ApplicationRecord
    #...

    attr_accessor :assembly

end

接下来这样做:

Assembly.find(1).assembly_parts.each do |assembly_part|
     part = assembly_part.part
     part.assembly = assembly_part.assembly #only valid through the current process
end

通过使用attr_accessor,您也可以在没有连接模型实现的情况下执行此操作。

上述解决方案无需新的迁移。可能存在轻微的拼写错误或语法错误,因为我在手机屏幕上执行此操作。 无论如何,我希望它有所帮助。

答案 1 :(得分:0)

这只是一个想法

如果您转到http://api.rubyonrails.org/并选择Active Record/Associations,您会看到有2个班级

1)Collection Proxies

2)Class Methods

但你也可以看到Association的类和模块,但我相信你应该修补Collection Proxies class

所以你在lib/core_ext/active_record/associations/collection_proxy.rb中创建了一个类,并在服务器启动时为required创建了一个初始化器。

如果这是你想要实现的目标

Assembly.find(1).parts.each do |part|

  the_calling_assembly = part.assembly_that_referenced_me()

end

你可以创建一个method来做到这一点。检查github上的CollectionProxy

是个好主意
module ActiveRecord
  module Associations
    class CollectionProxy < Relation
       def parent_instance
           Assembly.find(self.assembly_id)
       end
    end
  end
end

所以这不是一个完整的答案,可能我没有意识到你的功能的复杂性,但我建议你降低复杂性。

同时了解来自class的{​​{1}}是什么,因为这是您需要修补的内容。 (assembly_part