【问题标题】:Ruby on Rails - How to delegate to polymorphic associations?Ruby on Rails - 如何委托给多态关联?
【发布时间】:2012-11-01 15:52:05
【问题描述】:

是否可以在多态模型中将delegatehas_manyhas_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

【问题讨论】:

标签: ruby-on-rails ruby ruby-on-rails-3 ruby-on-rails-4 polymorphic-associations


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

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

    allow_nil 选项只会在不存在generable 的情况下防止NoMethodError 发生。但是,如果generable 存在,但generable 没有实现委托方法,您仍然会得到NoMethodError

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

    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
    

    使用此实现,如果 generable 没有响应该方法,@generic.file_url 将简单地返回 nil


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

    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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-03-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-30
      相关资源
      最近更新 更多