Ruby on rails Rails:如何检索多态'_类型';动态多态模型的列名?

Ruby on rails Rails:如何检索多态'_类型';动态多态模型的列名?,ruby-on-rails,ruby,ruby-on-rails-4,polymorphism,metaprogramming,Ruby On Rails,Ruby,Ruby On Rails 4,Polymorphism,Metaprogramming,我基本上想创建一个关注点,它将包含在所有多态模型中。这个关注点需要有一个动态setter方法来设置“\u type”列的值 module StiPolymorphable extend ActiveSupport::Concern included do define_method "#{magic_method_to_get_type_column}=" do |type_field| super(type_field.to_s.classify.constant

我基本上想创建一个关注点,它将包含在所有多态模型中。这个关注点需要有一个动态setter方法来设置“\u type”列的值

module StiPolymorphable
  extend ActiveSupport::Concern

  included do
    define_method "#{magic_method_to_get_type_column}=" do |type_field|
      super(type_field.to_s.classify.constantize.base_class.to_s)
    end
  end
end
我基本上希望访问父实例的所有地址,而不是Person实例

范例- 假设我有以下课程

class Person < ActiveRecord::Base
end

class Parent < Person end
class Teacher < Person end

class Address < ActiveRecord::Base
  include StiPolymorphable

  belongs_to :addressable, polymorphic: true
end
class-Person
现在,如果我试图访问父级的地址,它会给我零条记录,因为可寻址类型字段包含值“Person”

 Parent.first.addresses => #<ActiveRecord::Associations::CollectionProxy []> 
 Person.first.addresses => #<ActiveRecord::Associations::CollectionProxy [#<Address id: .....>]> 
Parent.first.addresses=>#
Person.first.addresses=>#

您可能对查看gem感兴趣,以便在包含模块时可以传递变量。但我还没有真正尝试过。希望能有所帮助。

您可能会对gem感兴趣,以便在包含模块时可以传递变量。但我还没有真正尝试过。希望能有所帮助。

我们会这样做:

module Shared::PolymorphicAnnotator
  extend ActiveSupport::Concern

  class_methods do
    # @return [String]
    #    the polymorphic _id column
    def annotator_id
      reflections[annotator_reflection].foreign_key.to_s
    end

    # @return [String]
    #    the polymorphic _type column
    def annotator_type
      reflections[annotator_reflection].foreign_type
    end 
  end

  included do
    # Concern implementation macro
    def self.polymorphic_annotates(polymorphic_belongs, foreign_key = nil)
      belongs_to polymorphic_belongs.to_sym, polymorphic: true, foreign_key: (foreign_key.nil? ? (polymorphic_belongs.to_s + '_id').to_s : polymorphic_belongs.to_s)
      alias_attribute :annotated_object, polymorphic_belongs.to_sym 

      define_singleton_method(:annotator_reflection){polymorphic_belongs.to_s} 
    end

    attr_accessor :annotated_global_entity 

    # @return [String]
    #   the global_id of the annotated object
    def annotated_global_entity
      annotated_object.to_global_id if annotated_object.present?
    end

    # @return [True]
    #    set the object when passed a global_id String
    def annotated_global_entity=(entity)
      o = GlobalID::Locator.locate entity

      write_attribute(self.class.annotator_id, o.id)
      write_attribute(self.class.annotator_type, o.class.base_class)
      true
    end
  end
end
在您的模型中:

class Foo
   include Shared::PolymorphicAnnotator
   polymorphic_annotates('belongs_to_name', 'foreign_key')
 end

我们这样做:

module Shared::PolymorphicAnnotator
  extend ActiveSupport::Concern

  class_methods do
    # @return [String]
    #    the polymorphic _id column
    def annotator_id
      reflections[annotator_reflection].foreign_key.to_s
    end

    # @return [String]
    #    the polymorphic _type column
    def annotator_type
      reflections[annotator_reflection].foreign_type
    end 
  end

  included do
    # Concern implementation macro
    def self.polymorphic_annotates(polymorphic_belongs, foreign_key = nil)
      belongs_to polymorphic_belongs.to_sym, polymorphic: true, foreign_key: (foreign_key.nil? ? (polymorphic_belongs.to_s + '_id').to_s : polymorphic_belongs.to_s)
      alias_attribute :annotated_object, polymorphic_belongs.to_sym 

      define_singleton_method(:annotator_reflection){polymorphic_belongs.to_s} 
    end

    attr_accessor :annotated_global_entity 

    # @return [String]
    #   the global_id of the annotated object
    def annotated_global_entity
      annotated_object.to_global_id if annotated_object.present?
    end

    # @return [True]
    #    set the object when passed a global_id String
    def annotated_global_entity=(entity)
      o = GlobalID::Locator.locate entity

      write_attribute(self.class.annotator_id, o.id)
      write_attribute(self.class.annotator_type, o.class.base_class)
      true
    end
  end
end
在您的模型中:

class Foo
   include Shared::PolymorphicAnnotator
   polymorphic_annotates('belongs_to_name', 'foreign_key')
 end

您能提供一些关于如何使用此模块的详细信息吗?我基本上是试图将此模块包括在我的应用程序中所有可能属于STI模型的多态模型中。@MaxWilliams我试图使多态实例访问所属STI模型的基类。如果这有任何意义的话。我会修改这个问题,给你一个更好的例子。你能举例说明你想要的结果吗。也许在OP.@usmanali中添加STI模型示例,我已经为clarityCan添加了一个示例,您可以提供更多关于如何使用此模块的详细信息吗?我基本上是试图将此模块包含在我的应用程序中所有可能属于STI模型的多态模型中。@MaxWilliams我试图使多态实例访问所属STI模型的基类。如果这有任何意义的话。我会修改这个问题,给你一个更好的例子。你能举例说明你想要的结果吗。也许在OP.@usmanali中添加了STI模型示例,我为Clarity添加了一个示例。现在这对我帮助不大。不过谢谢。现在这对我帮助不大。谢谢你。