我正在使用Rabl在rake任务中生成XML输出:
xml = Rabl.render @listings, 'feeds/listings', :format => :xml
# do stuff with xml
但是,我需要在引用的rabl视图文件中使用多个辅助方法,并且我会根据this question的答案得到NoMethodError
。
我尝试在rake任务使用的类中使用extends
和include
,但我仍然在辅助方法上遇到相同的错误:
require "#{Rails.root}/app/helpers/feeds_helper.rb"
class SerializeData
extends FeedsHelper
def perform
xml = Rabl.render @listings, 'feeds/listings', :format => :xml
# do stuff with xml
end
end
我的问题是:有没有办法在这种方式生成的rabl视图文件中使用辅助方法? (或者至少在某种程度上我仍然可以将它们作为rake任务中的字符串渲染?)帮助器方法被用于许多次,以便按照固定的要求正确地格式化各种数据,因此很难完全删除它们
答案 0 :(得分:6)
我最终得到了一个猴子补丁解决方案。
我注意到NoMethodFound
错误来自Rabl::Engine
类的实例,所以我在该类中包含了所需的路由和辅助方法,然后才能访问它们:
require "#{Rails.root}/app/helpers/feeds_helper.rb"
...
class Rabl::Engine
include Rails.application.routes.url_helpers
include FeedsHelper
end
另请注意,除了url
帮助者(例如path
和root_url
)之外,如果使用root_path
,则需要设置网址主机:
Rails.application.routes.default_url_options[:host] = "www.example.com"
我肯定更喜欢非猴子补丁解决方案,或者至少根据所呈现的操作的控制器,根据需要包含辅助工具。我等着接受这个,看看是否有人能想出这样的答案。
答案 1 :(得分:4)
您可以使用scope参数传入范围对象。因此,如果您可以访问包含帮助程序的对象,就像在视图上下文中那样,那么您可以传递它 例如:
<%= Rabl::Renderer.json(object_to_render, 'api/v1/object/show', view_path: 'app/views', scope: self).html_safe%>
因此,在视图上下文之外,您需要传入包含帮助程序的自定义对象以使其保持干净。 例如
class RakeScope
include FeedHelper
end
Rabl::Renderer.json(object_to_render, 'api/v1/object/show', view_path: 'app/views', scope: RakeScope.new() )
我没有尝试过第二种选择,但第一种选择效果很好。
答案 2 :(得分:0)
虽然问题不完全相同,但我从RSpec规范访问助手时遇到了类似的问题。我创建了一个辅助函数,它创建了一个范围,您可以使用该范围添加所需的任何帮助程序。以下内容让我可以访问路径和url辅助方法,类似的东西应该适用于Rake。
#spec/support/rabl_helper.rb
def render_rabl(object, options={})
options = {
format: 'json',
view_path: 'app/views',
file: example.example_group.top_level_description,
scope: RablScope.new
}.merge(options)
result = Rabl.render(object, options.delete(:file), options)
options[:format] == 'json' ? JSON.parse(result) : result
end
class RablScope
include Rails.application.routes.url_helpers
end