Rails: Render in a model

June 19, 2008

OK, this is really out there. Yes, the real answer is, “Don’t do it.”

Are you sure you aren’t going to be sad when the content of your database doesn’t change to keep up with your refactoring? Have you sufficiently explored other options and questioned the wisdom of what you are trying to do? Are you being asked to just to it anyway?

I found two approaches at http://davetroy.blogspot.com/2008/02/actsasrenderer-brings-output-to-models.html and http://blog.choonkeat.com/weblog/2006/08/rails-calling-r.html. I only tried the second of these, which didn’t like my use of polymorphic URLs and named routes in the template. I didn’t find the first approach before I had an interesting realization: if functional tests can do it then why can’t models?

def render_as_test(render_options, vars = {})
  controller = ApplicationController.new
  class << controller
    def set_instance_variables_and_render(render_options, vars)
      vars.keys.each do |k|
        instance_variable_set "@#{k}", vars[k]
      render render_options
  require 'action_controller/test_process'
  request = ActionController::TestRequest.new
  response = ActionController::TestResponse.new
  controller.process(request, response,
    render_options, vars).body

Now all my URLs generate. Use it responsibly. In fact, don’t use it at all. I am definitely not interested in pluginizing.



  1. Thanks, I had looked at those other examples and also had problems with URL generation. Extremely clever your approach! 🙂

  2. very clever, this is the first example that really works 🙂

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: