2010-04-12 100 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