Render_to_string из задачи рейка
Я хочу использовать задачу Rake для кэширования моей карты сайта, чтобы запросы на sitemap.xml
не выполнялись навсегда. Вот что я до сих пор:
@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>
Как я могу отобразить шаблон в строке из Rake?
Ответы
Ответ 1
Вот как я это сделал:
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)
Обратите внимание, что я преобразовал свой шаблон в частичный, чтобы сделать эту работу
Ответ 2
Существует post о том, как иметь доступ к ActionView:: Base методам и контексту из задачи rake.
Однако это monkeypatch. Почему бы не использовать кеш-механизм для выполнения кэширования?:)
Далее отредактируйте:
Функция 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}
)
)
Ответ 3
Недавно мне захотелось взять задачу рейка, определенную как упомянутый Horace Loeb, и перевести ее в автономную фоновое задание, но это нелегко перевести.
Вот моя реализация для Rails 2.3.x, потому что Реализация Rails 3. Я нашел, что это не сработает.
# 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.
Затем вы можете использовать класс выше, чтобы создать автономную таблицу для рендеринга ваших представлений в задаче грабли:
task :recent_projects => :environment do
template = OfflineTemplate.new(ProjectsHelper, PermissionsHelper)
puts template.render("projects/recent", :projects => recent_projects)
end