Calling Rails Render Partial in a Model or Background Task
Why?
You want to store raw HTML in the database for a given model and you want to do this with the ease of partials and not a bunch of nasty string manipulation.
Rails makes this difficult for you by not giving you access to the render method when not called from ActionController. However, you’d like to call the partial helper from within a model, or a background task (such as BackgrounDRb or Starling).
How?
As an example, let’s say you have a Page model made up of a title and a body. You’d like to cache what a rendered page would look like in the model as the attribute cached_content.
The old way. This really sucks.
class Page < ActiveRecord::Base
def write_cache
the_content = "<div class='title'>"
the_content += "<h1>#{self.title}</h1>"
the_content += "</div>"
the_content += "<div class='body'>"
the_content += "#{self.body}"
the_content += "</div>"
self.cached_content = the_content
self.save
end
end
The new way. This is so much easier and cleaner.
class Page < ActiveRecord::Base
def write_cache
self.cached_content = ActionView::Base.new(Rails::Configuration.new.view_path).render(:partial => "pages/show", :locals => {:page => self})
self.save
end
end
app/views/pages/_show.html.erb
<div class="title">
<h1>
<%= page.title %>
</h1>
</div>
<div class="body">
<%= page.body %>
</div>


Love the tip, it breaks though when your view code uses helper methods, to do this, I stole from Rails internal private method, initialize_template_class:
template_instance = ActionView::Base.new(Rails::Configuration.new.view_path)
template_instance.extend ApplicationController.master_helper_module
content = template_instance.render(:partial => self.view_path(self.profile) + ‘/show’, :locals => {:item => self})
I thank you for this!!
I take it link_to/url_for would fit into the situation Joe Goggins mentions above?
I’m trying to render a partial with some links to nested resources and I keep getting this error:
The error occurred while evaluating nil.url_for
I tried out Joe’s sample code as well, still no dice. Anyone have any thoughts?
thank u.