Rails

时间:2016-01-03 23:06:09

标签: ruby-on-rails ruby ruby-on-rails-4

我在ServicecontextServiceUsage之间有多态,has_many关联。 context模型(目前为ScenarioMapping)包含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转到关联对象(方案或映射)。

一种解决方案是为每个ServiceScenario添加与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关联会不会更好?

谢谢!

2 个答案:

答案 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}
"

我不认为元编程在这种情况下是一种矫枉过正的行为。