我正在使用动态调度来定义继承自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 ...),但在第二次调用时总是失败。
我想了解为什么会发生这种情况以及我可以做些什么来解决这个问题。
答案 0 :(得分:1)
进一步研究,我发现self.site
在我提出要求时并没有真正改变。它告诉我它在日志中正在发生变化,但它确实存在! self.site
在第一个调用的方法中不会从其初始设置状态更改。我有一个关于为什么这不起作用的理论以及使其工作的解决方法。
首先,我的理论:
当调用任何一个定义的类方法时,设置site
。由于site
超出了被调用的类方法的范围,因此一旦初始设置它,就不能再进行更改。
一个例子:
Invoice.get_details
Invoice.site
最初设置为“localhost:8080 / Invoice / getDetails”
Invoice.get_pending_notifications
Invoice.site
无法更改,因为它已被定义为“localhost:8080 / Invoice / getDetails”
以上只是一个有效的理论。
我是如何工作的:
删除对self.site
的所有引用,但初始集self.site = "localhost:8080"
除外,而是使用url字符串。 (在http://ofps.oreilly.com/titles/9780596521424/activeresource_id59243.html)
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
使用上面的代码,我可以调用任何定义的方法,每个方法指向不同的URL,没有问题。
答案 1 :(得分:0)
网站很可能无法正常重置。试试这个,它在ruby控制台下工作:
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