6

是否可以在多态模型中使用delegatehas_many关联has_one?这是如何运作的?

class Generic < ActiveRecord::Base
    ...

  belongs_to :generable, polymorphic: true

  delegate :file_url, to: :image, allow_nil: true
  delegate :type_cat, to: :cat, allow_nil: true
end

class Image < ActiveRecord::Base
   ...
  has_one :generic, as: generable, dependent: :destroy
end


class Cat < ActiveRecord::Base
   ...
  has_one :generic, as: generable, dependent: :destroy
end
4

2 回答 2

7

不确定这是否与您想要做的完全匹配,因为很难从您的示例中看出,但是......

class Generic < ActiveRecord::Base
  ...
  belongs_to :generable, polymorphic: true
  ...
  delegate :common_method, to: :generable, prefix: true
end

class Cat
  def common_method
    ...
  end
end

class Image
  def common_method
    ...
  end
end

允许您说以下内容:

generic.generable_common_method
于 2013-08-14T17:22:20.940 回答
0

不幸的是,delegate宏根本不适合多态关联——当然,除非您可以确保您的所有多态关联都实现了委托方法(哪种方式违背了目的)。

并且该选项只会在没有礼物的情况allow_nil下防止发生。但是,如果存在 a但未实现委托方法,您仍将获得 a 。NoMethodErrorgenerablegenerable generableNoMethodError

你最好的办法是像这样实现委托:

class Generic < ActiveRecord::Base
  ...

  belongs_to :generable, polymorphic: true


  def file_url
    generable.try(:file_url)
  end

  def type_cat
    generable.try(:type_cat)
  end

  ...
end

使用此实现,如果不响应该方法,@generic.file_url将简单地返回。nilgenerable


另一种选择是,为您提供DRYer 代码并避免使用一堆只说“在多态关联上尝试相同的方法名称”的方法,您可以在一行上定义所有这些方法并让它们像这样动态生成:

class Generic < ActiveRecord::Base
  ...

  belongs_to :generable, polymorphic: true

  METHODS_FOR_POLYMORPHIC_DELEGATION = %i(
    file_url
    type_cat
    something_else
    and_another_something_else
  )

  METHODS_FOR_POLYMORPHIC_DELEGATION.each do |method_name|
    define_method(method_name) { generable.try(method_name) }
  end

  ...
end
于 2018-06-28T20:43:05.640 回答