Rails 3:如何在 rake 任务中渲染 ERb 模板?

发布于 2024-10-04 14:28:11 字数 3422 浏览 1 评论 0原文

我正在使用 rake 渲染一个相当大的站点地图 HTML 文件。不幸的是,当我迁移到rails 3时,代码中断了。我当前的代码如下所示:

@controller = ActionController::Base.new
@controller.request = ActionController::TestRequest.new
@controller.instance_eval do
  @url = ActionController::UrlRewriter.new(request, {})
end

# collect data, open output file file

template = ERB.new(IO.read("#{RAILS_ROOT}/app/views/sitemap/index.html.erb"))
f.puts(template.result(binding))

此代码在2.3中工作,但在Rails 3中中断,因为url_for不再访问@controller,而是访问controller。 (我认为这就是原因。)

undefined local variable or method `controller' for #<Object:0x3794c>
/opt/local/lib/ruby/gems/1.8/gems/actionpack-3.0.1/lib/action_view/helpers/url_helper.rb:31:in `url_options'
/opt/local/lib/ruby/gems/1.8/gems/actionpack-3.0.1/lib/action_dispatch/routing/url_for.rb:132:in `url_for'
/opt/local/lib/ruby/gems/1.8/gems/actionpack-3.0.1/lib/action_view/helpers/url_helper.rb:99:in `url_for'
(erb):5
/Users/me/Documents/Projects/zvg2/lib/tasks/zvg.rake:452

我还尝试创建一个 ActionView 来这样做:

av = ActionView::Base.new(Rails::Application::Configuration.new(Rails.root).view_path, {
  # my assigns
}, @controller)
av.class_eval do
  include ApplicationHelper
end
f.puts(av.render(:template => "sitemap/index.html"))

但问题似乎是相同的,尽管 ActionView::Base.new 使用我的控制器。

undefined local variable or method `controller' for nil:NilClass
/opt/local/lib/ruby/gems/1.8/gems/activesupport-3.0.1/lib/active_support/whiny_nil.rb:48:in `method_missing'
/opt/local/lib/ruby/gems/1.8/gems/actionpack-3.0.1/lib/action_view/helpers/url_helper.rb:31:in `url_options'
/opt/local/lib/ruby/gems/1.8/gems/actionpack-3.0.1/lib/action_dispatch/routing/url_for.rb:132:in `url_for'
/opt/local/lib/ruby/gems/1.8/gems/actionpack-3.0.1/lib/action_view/helpers/url_helper.rb:99:in `url_for'
/opt/local/lib/ruby/gems/1.8/gems/actionpack-3.0.1/lib/action_dispatch/routing/url_for.rb:132:in `url_for'
/opt/local/lib/ruby/gems/1.8/gems/actionpack-3.0.1/lib/action_view/helpers/url_helper.rb:99:in `url_for'
/Users/me/Documents/Projects/zvg2/app/views/sitemap/index.html.erb:5:in `_app_views_sitemap_index_html_erb__757224102_30745030_0'
/opt/local/lib/ruby/gems/1.8/gems/actionpack-3.0.1/lib/action_view/template.rb:135:in `send'
/opt/local/lib/ruby/gems/1.8/gems/actionpack-3.0.1/lib/action_view/template.rb:135:in `render'
/opt/local/lib/ruby/gems/1.8/gems/activesupport-3.0.1/lib/active_support/notifications.rb:54:in `instrument'
/opt/local/lib/ruby/gems/1.8/gems/actionpack-3.0.1/lib/action_view/template.rb:127:in `render'
/opt/local/lib/ruby/gems/1.8/gems/actionpack-3.0.1/lib/action_view/render/rendering.rb:59:in `_render_template'
/opt/local/lib/ruby/gems/1.8/gems/activesupport-3.0.1/lib/active_support/notifications.rb:52:in `instrument'
/opt/local/lib/ruby/gems/1.8/gems/activesupport-3.0.1/lib/active_support/notifications/instrumenter.rb:21:in `instrument'
/opt/local/lib/ruby/gems/1.8/gems/activesupport-3.0.1/lib/active_support/notifications.rb:52:in `instrument'
/opt/local/lib/ruby/gems/1.8/gems/actionpack-3.0.1/lib/action_view/render/rendering.rb:56:in `_render_template'
/opt/local/lib/ruby/gems/1.8/gems/actionpack-3.0.1/lib/action_view/render/rendering.rb:26:in `render'
/Users/me/Documents/Projects/zvg2/lib/tasks/zvg.rake:450

使用 url_for 和 link_to 渲染模板的最佳实践是什么?我敢打赌,随着 Rails 变得更加模块化,应该有一个简单的方法来实现这一点?

提前致谢!扬

I am rendering a pretty huge sitemap HTML file with rake. Unfortunately, the code breaks when I migrate to rails 3. My current code looks like this:

@controller = ActionController::Base.new
@controller.request = ActionController::TestRequest.new
@controller.instance_eval do
  @url = ActionController::UrlRewriter.new(request, {})
end

# collect data, open output file file

template = ERB.new(IO.read("#{RAILS_ROOT}/app/views/sitemap/index.html.erb"))
f.puts(template.result(binding))

This code worked in 2.3, but breaks in Rails 3 as url_for does not access @controller anymore, but controller. (I think that's why.)

undefined local variable or method `controller' for #<Object:0x3794c>
/opt/local/lib/ruby/gems/1.8/gems/actionpack-3.0.1/lib/action_view/helpers/url_helper.rb:31:in `url_options'
/opt/local/lib/ruby/gems/1.8/gems/actionpack-3.0.1/lib/action_dispatch/routing/url_for.rb:132:in `url_for'
/opt/local/lib/ruby/gems/1.8/gems/actionpack-3.0.1/lib/action_view/helpers/url_helper.rb:99:in `url_for'
(erb):5
/Users/me/Documents/Projects/zvg2/lib/tasks/zvg.rake:452

I also tried creating an ActionView to do it like that:

av = ActionView::Base.new(Rails::Application::Configuration.new(Rails.root).view_path, {
  # my assigns
}, @controller)
av.class_eval do
  include ApplicationHelper
end
f.puts(av.render(:template => "sitemap/index.html"))

But the problem seems to be the same, although ActionView::Base.new takes my controller.

undefined local variable or method `controller' for nil:NilClass
/opt/local/lib/ruby/gems/1.8/gems/activesupport-3.0.1/lib/active_support/whiny_nil.rb:48:in `method_missing'
/opt/local/lib/ruby/gems/1.8/gems/actionpack-3.0.1/lib/action_view/helpers/url_helper.rb:31:in `url_options'
/opt/local/lib/ruby/gems/1.8/gems/actionpack-3.0.1/lib/action_dispatch/routing/url_for.rb:132:in `url_for'
/opt/local/lib/ruby/gems/1.8/gems/actionpack-3.0.1/lib/action_view/helpers/url_helper.rb:99:in `url_for'
/opt/local/lib/ruby/gems/1.8/gems/actionpack-3.0.1/lib/action_dispatch/routing/url_for.rb:132:in `url_for'
/opt/local/lib/ruby/gems/1.8/gems/actionpack-3.0.1/lib/action_view/helpers/url_helper.rb:99:in `url_for'
/Users/me/Documents/Projects/zvg2/app/views/sitemap/index.html.erb:5:in `_app_views_sitemap_index_html_erb__757224102_30745030_0'
/opt/local/lib/ruby/gems/1.8/gems/actionpack-3.0.1/lib/action_view/template.rb:135:in `send'
/opt/local/lib/ruby/gems/1.8/gems/actionpack-3.0.1/lib/action_view/template.rb:135:in `render'
/opt/local/lib/ruby/gems/1.8/gems/activesupport-3.0.1/lib/active_support/notifications.rb:54:in `instrument'
/opt/local/lib/ruby/gems/1.8/gems/actionpack-3.0.1/lib/action_view/template.rb:127:in `render'
/opt/local/lib/ruby/gems/1.8/gems/actionpack-3.0.1/lib/action_view/render/rendering.rb:59:in `_render_template'
/opt/local/lib/ruby/gems/1.8/gems/activesupport-3.0.1/lib/active_support/notifications.rb:52:in `instrument'
/opt/local/lib/ruby/gems/1.8/gems/activesupport-3.0.1/lib/active_support/notifications/instrumenter.rb:21:in `instrument'
/opt/local/lib/ruby/gems/1.8/gems/activesupport-3.0.1/lib/active_support/notifications.rb:52:in `instrument'
/opt/local/lib/ruby/gems/1.8/gems/actionpack-3.0.1/lib/action_view/render/rendering.rb:56:in `_render_template'
/opt/local/lib/ruby/gems/1.8/gems/actionpack-3.0.1/lib/action_view/render/rendering.rb:26:in `render'
/Users/me/Documents/Projects/zvg2/lib/tasks/zvg.rake:450

What's the best practice for rendering a template with rake that uses url_for and link_to? I bet as Rails just got more modular, there should be an easy way for just this?

Thanks in advance! Jan

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

离线来电— 2024-10-11 14:28:12

当我包含 Rails.application.routes.url_helpers 而不是 ActionView::Helpers::UrlHelper 时,其中一种方法有效。这目前有效:

include Rails.application.routes.url_helpers # brings ActionDispatch::Routing::UrlFor
include ActionView::Helpers::TagHelper

av = ActionView::Base.new(Rails.root.join('app', 'views'))
av.assign({
  :regions => @regions,
  :courts_by_region => @courts_by_region,
  :cities_by_region => @cities_by_region,
  :districts_by_region => @districts_by_region
})
f = File.new(file_name, 'w')
f.puts(av.render(:template => "sitemap/index.html"))
f.close

希望这对其他人有帮助。如果有更好的解决方案,我会很感兴趣。

另外,如何自动从绑定中获取分配的哈希值?

One of the approaches works when I include Rails.application.routes.url_helpers instead of ActionView::Helpers::UrlHelper. This works for now:

include Rails.application.routes.url_helpers # brings ActionDispatch::Routing::UrlFor
include ActionView::Helpers::TagHelper

av = ActionView::Base.new(Rails.root.join('app', 'views'))
av.assign({
  :regions => @regions,
  :courts_by_region => @courts_by_region,
  :cities_by_region => @cities_by_region,
  :districts_by_region => @districts_by_region
})
f = File.new(file_name, 'w')
f.puts(av.render(:template => "sitemap/index.html"))
f.close

Hope this helps others. If there is a better solution, I'd be interested.

Also, how do I automatically get a hash of assigns from binding?

⒈起吃苦の倖褔 2024-10-11 14:28:12

我通过做这样的事情成功了:

class Template < ActionView::Base
  include Rails.application.routes.url_helpers
  include ActionView::Helpers::TagHelper

  def default_url_options
    {host: 'yourhost.org'}
  end
end  

template = Template.new(Rails.root.join('app', 'views'))
template.assign(attendee: @attendee)
template.render(template: 'sitemap/index.html.erb')

I was successfull by doing something like this:

class Template < ActionView::Base
  include Rails.application.routes.url_helpers
  include ActionView::Helpers::TagHelper

  def default_url_options
    {host: 'yourhost.org'}
  end
end  

template = Template.new(Rails.root.join('app', 'views'))
template.assign(attendee: @attendee)
template.render(template: 'sitemap/index.html.erb')
提赋 2024-10-11 14:28:12

这对我有用(Rails 3):

class TaskActionView < ActionView::Base
  include Rails.application.routes.url_helpers
  include ApplicationHelper

  def default_url_options
     {host: 'example.com'}
  end
end

def action_view
  controller = ActionController::Base.new
  controller.request = ActionDispatch::TestRequest.new
  TaskActionView.new(Rails.root.join('app', 'views'), {}, controller)
end

action_view.render(:template =>"path/to/template")

这成功地包括了我的应用程序助手、标签助手和 url 助手。您需要将应用程序/环境主机正确放入 default_url_options 哈希中。

This is what worked for me (Rails 3):

class TaskActionView < ActionView::Base
  include Rails.application.routes.url_helpers
  include ApplicationHelper

  def default_url_options
     {host: 'example.com'}
  end
end

def action_view
  controller = ActionController::Base.new
  controller.request = ActionDispatch::TestRequest.new
  TaskActionView.new(Rails.root.join('app', 'views'), {}, controller)
end

action_view.render(:template =>"path/to/template")

This successfully included my application helper, tag helpers, and url helpers. You'll want to put your application/environments host properly into the default_url_options hash.

冰雪梦之恋 2024-10-11 14:28:12

这对我有用:

html = render_to_string(:index, layout: nil)

This is what worked for me:

html = render_to_string(:index, layout: nil)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文