将模型上的所有方法调用委托给关联

bad*_*wym 17 ruby activerecord ruby-on-rails ruby-on-rails-3

我有一个具有多态关联的ActiveRecord模型,如下所示:

class Reach < ActiveRecord::Base
  belongs_to :reachable, :polymorphic => true
end
Run Code Online (Sandbox Code Playgroud)

这个模型就像一个代理.我需要做的是将该对象上的所有方法调用转发给关联的对象:reachable.我想delegate在这里没有用,因为我必须明确命名我需要委派的所有方法.我需要delegate :all委托所有方法(不是all方法).

Ver*_*cus 17

你可以在这里做两件事:

  1. 较慢(性能方面)但更简单的方法是使用method_missing:

    class Reach < ActiveRecord::Base
    
      def method_missing(method, *args)
        return reachable.send(method, *args) if reachable.respond_to?(method)
        super
      end
    end
    
    Run Code Online (Sandbox Code Playgroud)
  2. 执行速度更快的方法是动态定义要委派的每个方法:

    class Reach < ActiveRecord::Base
    
      [:all, :my, :methods, :here].each do |m|
        define_method(m) do |*args|
          reachable.send(m, *args)
        end 
      end
    end
    
    Run Code Online (Sandbox Code Playgroud)

如果需要,您甚至可以以更动态的方式使用该方法,通过使用Reach类,查找在其上单独定义的方法,并仅定义Reachable上的方法.我会手工做,因为有一些你可能不想包括.

  • 如果您有一个要委派的方法列表,您可以像往常一样委托它们. (6认同)

CJ *_*cía 7

从Rails 5.1+开始,您可以委派所有未实现的内容delegate_missing_to :reachable

基本上,做您期望的。您可以在Api Doc上阅读更多内容

如果你是停留在以前的版本,则只是建议使用method_missing@Veraticus答案,是较少的性能,明智的提及,但我认为是更灵活的方法。


hof*_*anc 5

对于Rails,我做了以下工作:

class User < ApplicationRecord
  has_one :member
  delegate (Member.new.attributes.keys - User.new.attributes.keys), to: :member
end
Run Code Online (Sandbox Code Playgroud)

- User.new...是不覆盖现有的属性User(例如,created_at

我不确定这种方法如何与多态一起使用。