2010-04-12 66 views
10

我想使用Rake任务来缓存我的站点地图,以便sitemap.xml的请求不会永远持续。这是我到目前为止有:来自rake任务的render_to_string

@posts = Post.all 

    sitemap = render_to_string :template => 'sitemap/sitemap', :locals => {:posts => @posts}, :layout => false 
    Rails.cache.write('sitemap', sitemap) 

但是当我尝试运行此,我得到一个错误:

undefined local variable or method `headers' for #<Object:0x100177298> 

我怎样才能使一个模板,一个字符串从佣金中?

+0

这篇文章是有帮助 http://stackoverflow.com/questions/30725119/render-a -re-ra-rake-task – 2015-07-07 16:19:37

回答

9

我是这样做的:

av = ActionView::Base.new(Rails::Configuration.new.view_path) 
    av.class_eval do 
    include ApplicationHelper 
    end 

    include ActionController::UrlWriter 
    default_url_options[:host] = 'mysite.com' 

    posts = Post.all 

    sitemap = av.render 'sitemap/sitemap', :posts => posts 
    Rails.cache.write('sitemap', sitemap) 

请注意,我将我的模板的部分,使这项工作

+0

你在哪里使用default_url_options哈希? – 2015-07-07 15:46:25

4

有一个post关于如何能够从rake任务访问ActionView :: Base方法和上下文。

但是,这是一个monkeypatch。为什么不使用导轨'cache mechanism来完成缓存? :)

后来编辑: render_to_string函数在ActionController :: Base上下文中定义。

下面是一个解决方案,如何使它从耙子任务工作,取自omninerd

# In a rake task: 
av = ActionView::Base.new(Rails::Configuration.new.view_path) 
Rails.cache.write(
    "cache_var", 
    av.render(
    :partial => "view_folder/some_partial", 
    :locals => {:a_var => @some_var} 
) 
) 
+0

缓存机制非常棒,但有时你只是想定期将内容脱机生成到文件中。耙子任务是完美的地方 - 良好的联系。 – 2010-04-12 12:07:06

+0

我无法使用缓存,因为即使响应HTTP请求,也无法呈现站点地图,因为它需要30秒以上的时间,Heroku在30秒内超时HTTP请求 – 2010-04-12 16:33:24

+0

您有一点。那么,粘贴链接的方法对你有用吗? – 2010-04-12 17:33:02

1

最近我想采取这样定义霍勒斯·勒布提到rake任务并将其翻译成一个独立的背景作业,但不易翻译。

这是我对Rails 2.3.x的实现,因为我找到的Rails 3 implementation不起作用。

# Public: Template to render views outside the context of a controller. 
# 
# Useful for rendering views in rake tasks or background jobs when a 
# controller is unavailable. 
# 
# Examples 
# 
# template = OfflineTemplate.new(:users) 
# template.render("users/index", :layout => false, :locals => { :users => users }) 
# 
# template = OfflineTemplate.new(ProjectsHelper, PermissionsHelper) 
# template.render("projects/recent", :projects => recent_projects) 
# 
class OfflineTemplate 
    include ActionController::UrlWriter 
    include ActionController::Helpers::ClassMethods 

    # Public: Returns the ActionView::Base internal view. 
    attr_reader :view 

    # Public: Convenience method to 
    delegate :render, :to => :view 

    # Public: Initialize an offline template for the current Rails environment. 
    # 
    # helpers - The Rails helpers to include (listed as symbols or modules). 
    def initialize(*helpers) 
    helper(helpers + [ApplicationHelper]) 
    @view = ActionView::Base.new(Rails.configuration.view_path, {}, self) 
    @view.class.send(:include, master_helper_module) 
    end 

    private 

    # Internal: Required to use ActionConroller::Helpers. 
    # 
    # Returns a Module to collect helper methods. 
    def master_helper_module 
    @master_helper_module ||= Module.new 
    end 
end 

这可作为要点:https://gist.github.com/1386052

然后你就可以使用上面的类来创建一个OfflineTemplate呈现在rake任务的意见吧:

task :recent_projects => :environment do 
    template = OfflineTemplate.new(ProjectsHelper, PermissionsHelper) 
    puts template.render("projects/recent", :projects => recent_projects) 
end