2012-03-28 4 views
16

이 같은 다형성 연관이있는 액티브 모델을 데에 모델을 호출합니다. 내가해야 할 일은 해당 객체에 대한 모든 메소드 호출을 연관된 객체 :reachable에 전달하는 것입니다. 내가 명시 적으로 위임 할 필요가있는 모든 메소드의 이름을 지정해야하기 때문에 delegate이 도움이되지 않을 것이라고 생각합니다. 모든 메서드를 위임하려면 delegate :all과 같은 것이 필요합니다 (all 메서드가 아님).위임 모든 방법은 협회

답변

16

당신이 여기 할 수있는 두 가지가 있습니다

  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 
    
  2. 빠른 성능의 방법은하는 것을 위임 할 각 메소드를 동적으로 정의하십시오.

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

원할 경우 Reach 클래스를 사용하여 정의 된 메소드를 찾아서 Reachable에 정의 된 메소드 만 찾아보다 동적 인 방식으로 사용할 수도 있습니다. 나는 당신이 아마 포함하고 싶지 않을 일부가 있기 때문에 손으로 그것을 할 것입니다. 레일

+0

첫 번째 aproach에 관한 정보입니다. 'Reach' 객체에 메소드가 존재한다면이 메소드를 호출하지 않을 것입니까? – badawym

+0

그래, 미안하지만, 나는 '도달 할 수있다'는 뜻의 'reach'라고 타이핑했다. – Veraticus

+6

위임 할 메소드 목록이있는 경우 평소와 같이 위임 할 수 있습니다. – Andrew

4

, 나는 다음과 같은 한 :

class User < ApplicationRecord 
    has_one :member 
    delegate (Member.new.attributes.keys - User.new.attributes.keys), to: :member 
end 

- User.new...가에 기존의 속성을 무시하지 않는 것입니다을 User (예를 들어, created_at) 나는이 방법을 다형성으로 어떻게 작동하는지 모르겠어요

그러나.

1

세련미를 사용하여 문제에 접근하는 깔끔한 방법을 발견했습니다. 이미 표준 라이브러리에는 대상 객체에 대한 모든 메서드 호출의 위임을 허용하는 클래스가 있습니다. 이제 SimpleDelegator을 활용하기 위해 지금과 같은 후 초기화 콜백에 위임 목표를 설정

def self.include_delegator 
    mod = Module.new do 
    include refine(SimpleDelegator) { yield if block_given? } 
    end 
    self.send :include, mod 
end 
include_delegator 

:

Delegator and by extension SimpleDelegator 지금 바로 개선을 사용하여 상속하지 않고 상속 체인에 SimpleDelegator을 삽입하는 방법이
after_initialize do |instance| 
    __setobj__(instance.reachable) 
end 

이것은 SimpleDelegator에서 직접 상속 받고 건설에 위임을 설정하는 것과 같습니다. 위임하는 방법을 수동으로 관리하지 않으므로 누락 된 메서드를 사용하지 않아도됩니다.