2

동적 디스패치를 ​​사용하여 ActiveResource에서 상속 한 클래스에 여러 클래스 메서드를 정의하고 있습니다.동적 메서드 (ActiveResource를 사용하는 동적 리소스) 내에서 인스턴스 변수 변경

class Invoice < ActiveResource::Base 
    self.site = 'http://localhost:8080/' 

    def self.define(method) 
    define_singleton_method(method) do |params = {}| 
     site = self.site 
     self.site = "#{self.site}/Invoice/#{method.to_s.camelize(:lower)}" 

     puts "self.site -> #{self.site}" 
     results = Invoice.all(params: params) 

     self.site = site 
     puts "changing self.site back to #{site}"  

     return results 
    end 
    end 

    define :get_details 
    define :put_approval 
    define :get_attachment 
    define :get_pending_notifications 
end 

이 그것이 무엇이든 첫 번째 전화 (Invoice.get_details, Invoice.get_pending_notifications ...)을 위해 잘 작동하지만, 항상 두 번째 호출에 실패합니다.

왜 이런 일이 일어나고 있는지 이해하고 싶습니다. 문제를 해결하려면 어떻게해야합니까?

답변

1

더이 검토 한 결과, 내가 그것을 물어 때 self.site 실제로 변경되지 않은 것으로 나타났습니다. 그것은 로그에서 바뀌고 있다고 알려주지 만 거짓말입니다! self.site은 호출 된 첫 번째 메서드에서 초기 집합 상태에서 변경되지 않습니다. 나는 이것이 작동하지 않는 이유에 대한 이론을 가지고 있으며 그것을 작동 시키려면 해결 방법을 가지고있다.

첫째, 내 이론 :라고 정의 된 클래스 방법 중 하나, site가 설정되어

. site은 호출되는 클래스 메소드의 범위를 벗어나기 때문에 일단 초기에 설정되면 나중에 변경할 수 없습니다.

예 :

Invoice.get_details 

Invoice.site 처음에 설정되는 "로컬 호스트 : 8080/송장/getDetails"

Invoice.get_pending_notifications 
이미 로컬 호스트 "로 정의되기 때문에 Invoice.site 변경할 수없는

: 8080/인보이스/getDetails "

위의 내용은 작동 원리에 불과합니다.

제거 초기 설정 self.site = "localhost:8080"을 제외하고 self.site에 대한 모든 참조 대신에 URL 문자열을 사용 :이 작업을 가지고 어떻게

. 위의 코드를 사용하여

class Invoice < ActiveResource::Base 
    self.site = "localhost:8080" 
    def self.define(method) 
    define_singleton_method(method) do |params = {}| 
     url = "#{self.site}/Invoice/#{method.to_s.camelize(:lower)}" 

     # results = Invoice.all(params: params) <- Change this call to below 
     results = Invoice.find(:all, from: url, params: params) 

     return results 
    end 
    end 

    define :get_details 
    define :put_approval 
    define :get_attachment 
    define :get_pending_notifications 
end 

(http://ofps.oreilly.com/titles/9780596521424/activeresource_id59243.html에서 "사용자 정의 경로에서 자원 찾기"섹션에서) 나는 문제없이, 정의 된 방법 중 하나, 다른 URL을 가리키는 서로를 호출 할 수 있습니다.

0

사이트가 제대로 재설정되지 않을 가능성이 높습니다. 이 시도는 루비 콘솔에서 작동합니다

class Invoice < ActiveResource::Base 
    self.site = 'http://localhost:8080/' 

    def self.define(method) 
    define_singleton_method(method) do |params = {}| 
     site = self.site 
     begin 
     self.site = "#{self.site}/Invoice/#{method.to_s.camelize(:lower)}" 
     Invoice.all(params: params) 
     ensure 
     # this code will always be run, even if there is an exception above 
     # and it won't affect the original value returned above 
     self.site = site 
     end 
    end 
    end 

    define :get_details 
    define :put_approval 
    define :get_attachment 
    define :get_pending_notifications 
end 
+0

저는 방금 가지고있는 것을 시도했지만 저에게는 효과가없는 것 같습니다. 내가 먼저 호출하는 메서드에 따라 두 번째 호출에서 ActiveResource :: ForbiddenAccess 또는 ActiveResource :: ServerError가 표시됩니다. – Jeremiah