JVG*_*JVG 3 ruby model-view-controller ruby-on-rails
我对Rails很新,而且我做一些简单的事情,比如创建一个API调用,我有点不知所措.我已经建立了一个/reports有这个控制器的路线:
class ReportsController < ApplicationController
@client = # Api-accessing gem
@all_reports = []
def self.request_report
begin
puts "Step 1:"
step1 = @client.request_report(opts = {"max_count" => 1})
step1_result = step1.parse
puts "Done!"
puts step1_result
rescue Excon::Errors::ServiceUnavailable => e
puts "Didn't work"
logger.warn e.response.message
retry
end
end # End request_report
request_report
end
Run Code Online (Sandbox Code Playgroud)
这在我第一次加载/reports路由时正确调用外部API ,但是当我刷新页面时,代码不会重新运行.
也许我误解了控制器的用途?我是不是想把这段代码放到其他地方?或者是否存在缓存问题?
控制器的唯一的公共API是行动,这在HTTP请求做出响应.在您的情况下,get "/reports" => "reports#request_report"是与行动相对应的路线request_report.
但是,操作是实例方法,而不是类方法:
class ReportsController
def request_report # self.request_report would make this a class method!
# @todo get reports from somewhere and
# return some sort of response.
end
# any method call here happens when the class is evaluated.
end
Run Code Online (Sandbox Code Playgroud)
您将该操作声明为类方法,然后在评估ReportsController类时调用它.很抱歉,但关于控制器的一切都是错误的.
Rails惯例是调用该动作index.
Rails中的控制器只能由路由器(或您的测试框架)实例化.因此,他们肯定是放置可用的钻头和凸起的错误位置.如果你曾经看到有人在做ReportsController.new.foo或者ReportsController.foo当场解雇他们.
如果它是一个非常简单的一次性,你可以在控制器中将它放在私有方法中.
有些地方会在模型层上调用API - 但这是有争议的,因为ActiveRecord模型已经被赋予了权力和责任的鳃.
一个对我有用的解决方案是Service Objects.它们易于测试并且具有明确的单一责任.
class RequestReportService
def initalize(client)
@client = client
end
def call(opts = {})
begin
return @client.request_report(opts.merge("max_count" => 1))
rescue Excon::Errors::ServiceUnavailable => e
nil
end
end
end
class ReportsController
def index
@reports = RequestReportService.new(@client).call
end
end
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1091 次 |
| 最近记录: |