nginx Maintenance Page for Rails

Wednesday, August 12th, 2009

I recently moved one of my main Rails projects from a Mongrel/Pound stack to Thin and nginx. During this process, I was attempting to set up a maintenance page that would display whenever Thin was offline, but there appears to be some confusion on this topic. Below you will find my minimal solution for displaying a maintenance page for an nginx based rails deployment.

nginx conveniently supplies an error_page configuration option which can be used to specify an html page to be displayed whenever certain errors occur. When the proxied server is offline, such as when Thin or Mongrel is restarting, or you have it stopped while performing maintenance, nginx will return a generic “502 Bad Gateway” error. To replace this page with your own more aesthetically pleasing version, simply place an html file in the public directory of your rails app, and then place this line somewhere in the server section of the nginx config file for the site (which should reside in /etc/nginx/sites-available).

error_page 502 /offline.html;

Simply replace offline.html with the name of your error page, restart nginx, and you’ll be good to go. Here is a bit more context from the configuration file.

server {
  listen 80;

  error_page 502 /offline.html;

  location / {

Render Rails Templates Anywhere (even in a model)

Monday, July 20th, 2009

I can only dream of actually having the time to properly update this blog, but for the moment I’m simply posting a snippet that has been very useful to me.

Even though I love Rails, I hate the way it locks you into only working within its paradigm, making it virtually impossible to break out of the MVC box even when it makes far more sense to do so. One particularly bothersome case is when you need (for whatever reason) to render an ActionView template outside of a controller.

For instance, in an application I’m working on I allow users to customize automatically sent emails. These emails are templated using a custom class that allows the user to insert predefined tags into the message that are automatically replaced with information such as the recipients name, address, etc. One such tag is replaced by a summary of all the users registration information, and this summary is simply an ActionView template. This leads to the sticky part. The template class is prepared by a class method of my model, which needs to provide a block to the template class capable of rendering this summary page.

Enter the render_anywhere method!

def render_anywhere(partial, assigns)
  view =, assigns)
  ActionView::Base.helper_modules.each { |helper| view.extend helper }
  view.extend ApplicationHelper
  view.render(:partial => partial)

Simply place this method in a file in your lib directory, or even in environment.rb, it really doesn’t matter. Then you can just call it (from literally anywhere) as shown below:

render_anywhere('/students/summary', { :student => student })

You can also add controller specific helpers if necessary, by simply adding more view.extend lines as above.

(thanks to Compulsivo for much of this code)

Better Redirects in Rails

Saturday, March 22nd, 2008

Its been a very long time since I posted to this blog, but I thought I might share some tricks I’ve developed for handling a few special types of redirects a bit more gracefully in Ruby on Rails.

Note: all of the code in this post, except for one view helper method, should be placed in your ApplicationController (app/controllers/application.rb) from which all other controllers inherit.

Most people who have read any book on Rails will probably have run into the redirect_to_index method, which goes something like this:

def redirect_to_index(msg = nil)
  flash[:notice] = msg if msg
  redirect_to :action => 'index'

This method is mainly useful when you the user has just edited an object, and you now want to display a message in the flash like “User updated successfully”, and then redirect them back to the index action. But what about if you don’t want to redirect the user back to the index action, or if you want to send them to another controller? Say hello to the flash_redirect method:

def flash_redirect(msg, *params)
  flash[:notice] = msg

flash_redirect accepts both a message to be put in the flash, along with the params for redirect_to, so that you can flash a message and then send the user anywhere you please.

These two methods by themselves are pretty useful, but what about the common situation where a user attempts to go somewhere they don’t have permission to, or that they need to login before accessing? In the Rails book, this is handled by storing the original url in the session, and then redirecting to the other action, which then has to do special session processing when it returns the user to the original action. Encapsulating all this code into some easily reusable methods would look like this:

# redirect somewhere that will eventually return back to here
def redirect_away(*params)
  session[:original_uri] = request.request_uri

# returns the person to either the original url from a redirect_away or to a default url
def redirect_back(*params)
  uri = session[:original_uri]
  session[:original_uri] = nil
  if uri
    redirect_to uri

redirect_away handles sending the user away to another action, and redirect_back will send them back to either the action they were redirected away from, or to a default action. One possible use for these could be to require authorization before accessing an action:

class AdminController < ApplicationController
  before_filter :require_admin, :except => 'login'

  def index 
    # unauthorized people shouldn't be able to access this

  def login
    # handle login
    if User.authorize(params[:username], params[:password])
      session[:admin] = true
      redirect_back(:action => 'index')


  def require_admin
    unless session[:admin]
      flash[:notice] = "You must be logged in"
      redirect_away(:action => 'login')
      return false

So now we can redirect a user away from an action, and then send them back to it later on. But what if we want to let a user click a link to go somewhere, and then send them back where they came from later? With a simple helper method and a before filter, we can accomplish just that:

# app/helpers/application_helper.rb
def link_away(name, options = {}, html_options = nil)
  link_to(name, { :return_uri => url_for(:only_path => true) }.update(options.symbolize_keys), html_options)

# app/controllers/application.rb
before_filter :link_return


# handles storing return links in the session
def link_return
  if params[:return_uri]
    session[:original_uri] = params[:return_uri]

Now in the view, you can write:

<%= link_away "Edit post", :controller => '/admin/posts', :action => 'edit', :id => post %>

And as long as the controller uses redirect_back, the user can click the link, and when they’re done editing, they will come right back to where they clicked the link. This trick is probably the most useful from a usability standpoint, given that nothing annoys a user more than having to manually navigate back to where they were after each change.

I hope you find these techniques useful for writing more user friendly and concise code!

Updated Ruby Tutorial

Friday, August 17th, 2007

I’ve just updated my Ruby tutorial with a ton of new content. Some of the added sections include:

  • A regular expression (regex) reference
  • An explanation of the rather confusing rules behind block scope
  • An example on the use of the Ruby case statement (similar to the C switch statement)
  • How to write your own attr_accessor method (and understand class_eval in the process)
  • Several new core functions and methods

I don’t know if anyone else is finding my reference helpful, but it has definitely aided me in understanding the intricacies of Ruby.

Fixing div.fieldWithErrors in Ruby on Rails

Saturday, May 5th, 2007

Rails’ form helpers are incredibly handy in quickly writing form code, however their error handling code leaves something to be desired. By default, when a field has errors associated with it, the input is wrapped in a div of class “fieldWithErrors”. Unfortunately, this behavior requires you to explicitly change the div to display inline so it doesn’t make the input appear on the next line after the name of the field. I have also had some trouble getting this setting to work in Safari, although that may just be my problem and not Safari’s.

Fortunately, fixing this annoying little gotcha is as easy as adding a single line to the end of your environment.rb file: (I’ve split it into two lines so it will fit on the page, just remove the line break)

ActionView::Base.field_error_proc = { |html_tag, instance|
"<span class=\"fieldWithErrors\">#{html_tag}</span>" }

I know many people have already written about this problem, but I wanted to have my own record of it for easy reference 😉

The Dangers of Direct Assignment in Rails with[:user])

Monday, April 30th, 2007

Although it is used in the vast majority of Ruby on Rails tutorials, putting data from a form directly into an object using a statement such as[:user]) can actually be an extreme security risk.

To understand why, it is necessary to first explain how this statement works. Forms generated by Rails’ default form helpers look something like this:

Username: <input type="text" name="user[username]" />
Password: <input type="password" name="user[password]" />

The user[name] format is automatically converted by rails into a hash in the params variable, which would contain the following if this form were submitted:

params[:user] = {
    :username => "Bob"
    :password => "Secret"

Since accepts a hash of key/value pairs that will become the initial values of all the attributes of the returned object,[:user]) is simply taking the hash of values passed in from the HTML form for the user, and directly setting them in the new object. The simplicity of this operation is also its downfall. For instance, a user could modify your registration form (either using a browser plugin our by downloading it to their computer) to the following:

Username: <input type="text" name="user[username]" />
Password: <input type="password" name="user[password]" />
<input type="hidden" name="user[admin]" value="1" />

If your user model used a boolean attribute called admin to specify whether a user had admin privileges, when the form is submitted your code would unwittingly grant the user admin access. Because params[:user][:admin] was set to 1 in the hash passed in from the form, it is automatically set to 1 in the user object and saved to the database.

The Solution

Fortunately, this security hole is easy to fix using either of two simple statements provided by ActiveRecord in your model code. The first is attr_protected, which can be used thus:

class User < ActiveRecord::Base
    attr_protected :admin

This simple statement, which can accept multiple parameters, sets up a blacklist of attributes that cannot be set from the hash passed to, effectively filtering the input and patching the security hole.

The second alternative, attr_accessible, uses a white-listing approach instead. Only those attributes explicitly given to attr_accessible can be set from the hash passed to, any others will be ignored.

class User < ActiveRecord::Base
    attr_accessible :username, :password

Which approach you use depends entirely on preference, whether you think you are more likely to forget to protect sensitive attributes or to allow access to non-sensitive ones. Whichever method you choose, protected attributes can always be set by calling their accessor method, such as user.admin = 1.

For more information on this topic, see the Ruby on Rails manual.

A Further Warning on Associations

According to this article, the mass assignment security hole also affects collections and associations, such as a User having many Articles. By specially crafting a form submission, a user could claim any article as their own, simply using something similar to:

<input type="hidden" name="user[article_ids][]" value="5" />

This is because rails automatically creates attribute accessors like article_ids for has_many associations, which accept an array of ids to associate the object with. The form snippet above would add a new id to that array, and give the user ownership/authorship of that article. The author of the above article makes the case that, because of this hole (and other possibly others opened up by associations and other rails magic), it is a better idea to explicitly white-list attributes using attr_accessible, rather than attr_protected. This way, something like article_ids, which most developers don’t know about (myself included), won’t open up your application to exploitation. Ignorance is not always bliss.

Although this methodology is somewhat more in the spirit of Python than Rails, it is undoubtedly the safest. Explicitly defining which variables can be passed in through a form is also the method taken by Formencode, a widely used validation library for Python.

Ruby – A Lightning Tutorial

Saturday, March 31st, 2007

Whenever I’m learning a new programming language, I find it helpful to keep notes on what I learn. Ruby is no exception, except this is the first time I have tried compiling these notes into more of a tutorial.

You can see the first draft of it (or the Alpha version), over here.

Its style is based on the assumption that you can always find out about the practical usage of the language, its classes, functions, and methods, later. Lightning Tutorials (yes, I intend to write more) attempt to teach only the absolute essential parts of the language, its syntax, idioms, features, and gotchas. Because they do not explain anything but the most fundamental parts of the language, they can be very concise. However, you must already be a relatively competent programmer to understand them. I don’t explain what terms such as “instance variables” or “classes” mean, as they are not intended to be an introduction to programming, but rather a quickstart guide for experienced programmers who wish to get up and running on a new language quickly. After all, you can always read the language docs later.

Ruby on Rails, Here I Come!

Thursday, January 4th, 2007

I just got my Agile Web Development with Rails book! Now I can learn rails and start writing killer software 10 times faster than I could with PHP!

end hype

Seriously, now I can actually see how easy it is to develop “real” software with rails, rather than the ten minute basically worthless blog software that doesn’t even have authentication. I think building Flowpad v2 with it (the next version of the tournament registration software) will be the ultimate test of its abilities.

Hopefully Rails will be up to the task.