在Rails 4中渲染rake任务/后台作业/模型中的部分/视图

我已经阅读了很多关于在rake任务/后台作业/模型中渲染Rails部分和视图的内容。 我在Stackoverflow和Web上发现的绝大多数事情都描述了在Rails 3中工作的方法,但它们看起来已经过时了,我没有让它们工作(即使花了很多时间进行实验)。

那么,如何在Rails 4中的后台作业中渲染局部?

这是我迄今为止制定的最佳方法(在控制台中演示)。

c = ApplicationController.new result = c.render_to_string(partial: 'tweets/tweet', locals: {tweet: Tweet.first}) # => # Tweet Load (0.8ms) SELECT "tweets".* FROM "tweets" ORDER BY "tweets"."id" ASC LIMIT 1 # Author Load (0.6ms) SELECT "authors".* FROM "authors" WHERE "authors"."id" = $1 ORDER BY "authors"."id" ASC LIMIT 1 [["id", 1]] # Status Load (0.6ms) SELECT "statuses".* FROM "statuses" WHERE "statuses"."twitter_id" = 367523226848866304 LIMIT 1 # Rendered tweets/_tweet_body.html.slim (17.5ms) # Rendered tweets/_resolved_tweet.html.slim (23.7ms) # Rendered tweets/_tweet.html.slim (28.1ms) # ActionView::Template::Error: undefined method `tweet_path' for #<#:0x007fb21cb009e8> # from /Users/thomasklemm/.rbenv/versions/2.0.0-p195/lib/ruby/gems/2.0.0/gems/actionpack-4.0.0/lib/action_dispatch/routing/polymorphic_routes.rb:129:in `polymorphic_url' 

有任何想法吗? 提前致谢!

更新tweet_path提到的tweet_path确实没有定义。 使用实例变量链接到path = link_to 'Tweet', [@project, tweet] (slim模板)导致此错误= link_to 'Tweet', [@project, tweet]该实例变量将存在于从某个控制器inheritance的视图中,但在此上下文之外呈现时则不会。 我通过适当的关联解决了这个问题而不是= link_to 'Tweet', [tweet.project, tweet]

这是我从许多来源编译的内容以及在Rails 4中对我有用的内容。

使用此Renderer类,您应该能够在任何上下文中呈现Rails 4视图和部分,例如后台作业,服务对象,模型,工作者,您可以命名它。

 # app/services/renderer.rb # Render views and partials in rake tasks, # background workers, service objects and more # # Use: # # class MyService # def render_stuff # result = renderer.render(partial: 'tweets/tweet', locals: {tweet: Tweet.first}) # # or even # result = renderer.render(Tweet.first) # end # # private # # def renderer # @renderer ||= Renderer.new.renderer # end # end # class Renderer def renderer controller = ApplicationController.new controller.request = ActionDispatch::TestRequest.new ViewRenderer.new(Rails.root.join('app', 'views'), {}, controller) end end # app/services/view_renderer.rb # A helper class for Renderer class ViewRenderer < ActionView::Base include Rails.application.routes.url_helpers include ApplicationHelper def default_url_options {host: Rails.application.routes.default_url_options[:host]} end end 

更新

似乎有一个更简单的解决方案: http : //makandracards.com/makandra/17751-render-a-view-from-a-model-in-rails

 ApplicationController.new.render_to_string( :template => 'users/index', :locals => { :@users => @users } ) # Mind the weird syntax to set @ variables in :locals. 

更新2

有一个名为render_anywhere的gem允许从任何地方调用“render”:模型,后台作业,rake任务等。

更新3

Rails 5中 ,渲染器已被解压缩,可以从后台作业和其他地方独立使用:

 ApplicationController.renderer.render( partial: 'messages/message', locals: { message: message } ) 

对于Rails <= 4.2,可以使用backport_new_renderer gem向后移植此功能。

确保在作业中加载rails环境。 如果已经完成,您可以尝试以下方法:

 include Rails.application.routes.url_helpers