render_to_string из грабли - PullRequest
       28

render_to_string из грабли

10 голосов
/ 12 апреля 2010

Я хочу использовать задачу 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?

Ответы [ 3 ]

9 голосов
/ 12 апреля 2010

Вот как я это сделал:

  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)

Обратите внимание, что я преобразовал свой шаблон в частичный, чтобы сделать эту работу

4 голосов
/ 12 апреля 2010

В сообщении содержится информация о том, как получить доступ к методам ActionView :: Base и контексту из задачи rake.

Однако, это обезьяна. Почему бы не использовать механизм кэширования рельсов для выполнения кэширования? :)

Позже редактировать: Функция render_to_string определена в контексте ActionController :: Base.

Ниже приведено решение о том, как заставить его работать из задач rake, взятое из 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}
  )
)
1 голос
/ 22 ноября 2011

Недавно я хотел взять задание на грабли, определенное, как упоминал Гораций Леб, и перевести его в автономную фоновую работу, но ее нелегко перевести.

Вот моя реализация для 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.

Затем вы можете использовать приведенный выше класс для создания шаблона OfflineTemplate для отображения ваших представлений в задаче rake:

task :recent_projects => :environment do 
  template = OfflineTemplate.new(ProjectsHelper, PermissionsHelper)
  puts template.render("projects/recent", :projects => recent_projects)
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...