2010-04-12 20 views
10

Ich möchte eine Rake-Aufgabe verwenden, um meine Sitemap zwischenzuspeichern, so dass Anfragen für sitemap.xml nicht ewig dauern. Hier ist, was ich bisher:render_to_string von einer Rake-Aufgabe

@posts = Post.all 

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

Aber wenn ich versuche, dies zu laufen, bekomme ich eine Fehlermeldung:

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

Wie kann ich eine Vorlage in eine Zeichenfolge zu rendern, von innerhalb Rake?

+0

dieser Artikel hilfreich http://stackoverflow.com/questions/30725119/render-a -view-from-a-rake-task –

Antwort

9

Hier ist, wie ich es tat:

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) 

Bitte beachte, dass ich meine Vorlage zu einer teilweisen umgewandelt, um diese Arbeit zu machen

+0

Wo verwenden Sie default_url_options Hash? –

4

Es gibt eine post über wie auf ActionView :: Base-Methoden und Kontext von Rake-Task zugreifen können.

Dies ist jedoch ein Monkeypatch. Warum verwenden Sie nicht die cache mechanism Rails der Caching? :)

Später bearbeiten: Die render_to_string Funktion in Action definiert :: Base Kontext.

Im Folgenden finden Sie eine Lösung, wie Sie aus Rake-Tasks arbeiten können, die aus omninerd stammen.

# 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

Der Cache-Mechanismus ist großartig, aber manchmal wollen Sie den Inhalt nur offline in eine Datei erzeugen. Eine Rake-Aufgabe ist der perfekte Ort dafür - gute Verbindung. –

+0

Ich kann das Caching nicht verwenden, da ich die Sitemap nicht einmal als Antwort auf eine HTTP-Anfrage rendern kann, da es mehr als 30 Sekunden dauert und Heroku HTTP-Anfragen nach 30 Sekunden auslöst –

+0

Sie haben einen Punkt. Funktioniert der Ansatz von der eingefügten Verknüpfung für Sie? –

1

Vor kurzem habe ich eine Harke Aufgabe definiert nehmen wollte wie Horace Loeb erwähnt und es in einen eigenständigen Hintergrundjob übersetzen, aber es hat nicht leicht übersetzt.

Hier ist meine Implementierung für Rails 2.3.x, weil die Rails 3 implementation, die ich gefunden habe, nicht funktionieren würde.

# 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 

Dies ist im Wesentlichen verfügbar: https://gist.github.com/1386052.

Dann können Sie die Klasse verwenden, über einen OfflineTemplate erstellen Sie Ihre Ansichten in einer Harke Aufgabe zu machen:

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