我基本上想要创建一个将包含在所有多态模型中的关注点。这个问题需要有一个动态setter方法,它设置'_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
我基本上想要访问Parent实例的所有地址而不是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
现在,如果我尝试访问Parent的地址,它会给我零记录,因为addressable_type字段包含值'Person'。
Parent.first.addresses => #<ActiveRecord::Associations::CollectionProxy []>
Person.first.addresses => #<ActiveRecord::Associations::CollectionProxy [#<Address id: .....>]>
答案 0 :(得分:0)
您可能有兴趣查看Modularity gem,以便在您包含模块时传递变量。但是哈文真的没有尝试过。希望它有所帮助。
答案 1 :(得分:0)
我们这样做:
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