我在Service
和context
到ServiceUsage
之间有多态,has_many关联。 context
模型(目前为Scenario
和Mapping
)包含ServiceConsumer
mixin,声明了以下关联:
has_many :service_usages, as: :context, dependent: :destroy
has_many :services, through: :service_usages, dependent: :destroy
ServiceUsage
,连接表,定义以下关联:
belongs_to :service, inverse_of: :service_usages
belongs_to :context, inverse_of: :service_usages, polymorphic: true
Service
目前有:
has_many :service_usages, inverse_of: :service
使用当前设置,无法从service
转到关联对象(方案或映射)。
一种解决方案是为每个Service
和Scenario
添加与Mapping
的显式关联,如下所示:
has_many :scenarios, through: :service_usages, source: :subject, source_type: Scenario
我认为有更好的方法可以避免在Service
上明确定义关联。
我一直在考虑这些问题:
module ServiceConsumer
extend ActiveSupport::Concern
included do
has_many :service_usages, as: :context, dependent: :destroy
has_many :services, through: :service_usages, dependent: :destroy
Service.class_eval <<-EOF
has_many #{self.to_s.underscore.pluralize.to_sym}, through: :service_usages,
source: :context,
source_type: ::#{self}
EOF
end
end
我们的想法是,当模型包含ServiceConsumer
关注点时,它会在Service
上为该特定模型定义has_many
关联。
这听起来很棒,但我还没有成功地让它发挥作用。
任何想法/意见/建议将不胜感激。你认为这太模糊了吗?为每个多态相关模型明确定义has_many
上的Service
关联会不会更好?
谢谢!
答案 0 :(得分:1)
has_many #{self.to_s.underscore.pluralize.to_sym}
您关心的这条线从根本上是错误的。就像Scenario
包含它一样,它会在has_many :scenario
模型中转换为Scenario
,这没有任何意义。
另一方面,您必须在干编程和元编程之间保持平衡。不必要的Metaprogram可能会过度使用。
答案 1 :(得分:0)
这对我有用。
Tag.class_eval %Q"
has_many :#{model_name.plural}, through: : service_usages, source: :context, source_type: #{model_name.name}
"
我不认为元编程在这种情况下是一种矫枉过正的行为。