问题:
如何告诉 ActiveRecord 在存储/查询关联类型列时不包含关联类的命名空间?
当前状况:
考虑以下类定义:
class PageTemplateA < ActiveRecord::Base
has_many :type_a_pages, :as => :pageable, :class_name => 'TypeAPage', :inverse_of => :pageable
end
##### The following class is implemented through STI.
class TypeAPage < Page
belongs_to :pageable, :class_name => 'PageTemplateA', :inverse_of => :type_a_page
end
class Page < ActiveRecord::Base
belongs_to :pageable, :polymorphic => true
end
总结一下:
-
TypeAPage
数据库表中通过STI实现,pages
. -
TypeAPage
与PageTemplateA
相关联通过多态关联(与pages.pageable_type
关联时PageTemplateA
为PageTemplateA
)
我想要做出的改变:
我想将上述所有模型移至新的命名空间中,例如 PagesEngine
,所以我对 PageTemplateA
的定义看起来像:
module PagesEngine
class PageTemplateA < ActiveRecord::Base
has_many :type_a_pages, :as => :pageable, :class_name => 'TypeAPage', :inverse_of => :pageable
end
end
这工作正常,除了 ActiveRecord 推断 pageable_type
对于 TypeAPage
成为PagesEngine::PageTemplateA
.
如何告诉 ActiveRecord 不包含命名空间,并解析 pageable_type
至PageTemplateA
而不是PagesEngine::PageTemplateA
?
最佳答案
对于保存多态关系的模型,您可以设置self.store_full_sti_class = false
或从将store_full_sti_class设置为false的抽象模型继承。
module PagesEngine
class Page < Base
# self.store_full_sti_class = false
belongs_to :pageable, polymorphic: true
end
class TypeAPage < Page
belongs_to :pageable,
class_name: 'PageTemplateA',
inverse_of: :type_a_pages
end
end
使用与关联模型 (PagesEngine::PageTemplateA) 匹配但没有命名空间的类型列 (pageable_type) 显式确定关系 (type_as_pages) 的范围。
module PagesEngine
class PageTemplateA < Base
has_many :type_a_pages,
-> { where(pageable_type: 'PageTemplateA') },
foreign_key: :pageable_id,
inverse_of: :pageable
end
end
最后重写Belongs_to方法并自定义Active Record属于多态关联。
module PagesEngine
class Base < ActiveRecord::Base
self.abstract_class = true
self.store_full_sti_class = false
def self.belongs_to(name, scope = nil, options = {})
super(name, scope, options).tap do |hash|
reflection = hash[name.to_s]
def reflection.association_class
if polymorphic?
BelongsToPolymorphicAssociation
else
super
end
end unless store_full_sti_class
end
end
end
class BelongsToPolymorphicAssociation < ActiveRecord::Associations::BelongsToPolymorphicAssociation
def klass
type = owner[reflection.foreign_type]
type.presence && PagesEngine.const_get(type)
end
end
end
关于ruby-on-rails - ActiveRecord 模型 'type' 多态关联列包括关联模型的命名空间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37243116/