2010-04-12 18 views
10

Quiero utilizar una tarea de Rake para almacenar en caché mi sitemap de modo que las solicitudes de sitemap.xml no demorarán para siempre. Esto es lo que tengo hasta ahora:render_to_string desde una tarea de rastreo

@posts = Post.all 

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

Pero cuando trato de ejecutar esto, me sale un error:

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

¿Cómo puedo reproducir una plantilla a una cadena desde dentro Rake?

+0

este artículo está atento http://stackoverflow.com/questions/30725119/render-a -view-from-a-rake-task –

Respuesta

9

Así es como lo hice:

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) 

Tenga en cuenta que Convertí mi plantilla a un parcial de hacer este trabajo

+0

donde usas default_url_options hash? –

4

Hay un post sobre cómo poder acceder a los métodos ActionView :: Base y el contexto de la tarea de rake.

Sin embargo, esto es un monopatch. ¿Por qué no utilizar los rieles 'cache mechanism para lograr el almacenamiento en caché? :)

Edición posterior: La función render_to_string se define en el contexto ActionController :: Base.

A continuación se muestra una solución sobre cómo hacer que funcione desde tareas de rake, tomadas desde 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

El mecanismo de caché es genial, pero a veces realmente solo desea generar periódicamente el contenido sin conexión en un archivo. Una tarea de rake es el lugar perfecto para eso, buen enlace. –

+0

No puedo usar el almacenamiento en caché porque no puedo representar el mapa del sitio ni siquiera una vez en respuesta a una solicitud HTTP, ya que demora más de 30 segundos y Heroku agota las solicitudes HTTP a los 30 segundos –

+0

Tiene sentido. Entonces, ¿el enfoque del enlace pegado funciona para usted? –

1

Recientemente me quería tomar una tarea rake definido como Horacio Loeb mencionó y traducirlo a un trabajo de fondo independiente, pero no se tradujo fácilmente.

Aquí está mi implementación para Rails 2.3.x porque el Rails 3 implementation que encontré no funcionaría.

# 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 

Esto está disponible como una esencia: https://gist.github.com/1386052.

continuación, puede utilizar la clase anterior para crear un OfflineTemplate para hacer sus puntos de vista en una tarea rake:

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