Notes posted to Ruby on Rails

RSS feed
May 27, 2010
2 thanks

Use :path_prefix for the namespace

Resources are added after the :path_prefix. However if you use a :path_prefix on a resource, it overrides the namespace path instead of appending to it (as I think it should).

Here is what I wrote to create a versioned API access path.

map.namespace :api3, :path_prefix=>"/api/v3" do |api|
  api.resources :posts
  api.resources :comments, :path_prefix=>"/api/v3/post/:post_id"

This will create routes like

path: /api/v3/posts/1 
named_route: api3_post()
May 26, 2010
0 thanks

Prevent transactional fixtures for a specific test class

If you want to prevent a specific group of tests from being run inside a transaction, just define inside your test class the methods teardown_fixtures and setup_fixtures with empty bodies.

May 26, 2010
0 thanks

Prevent transactional fixtures for a specific suite

If you want to prevent a specific group of tests from being run inside a transaction, just define inside your test class the methods teardown_fixtures and setup_fixtures with empty bodies.

May 18, 2010
2 thanks

How using Array methods

It’s not possible to use Array methods with a scope because it’s not an Array but an ActiveRecord::NamedScope::Scope :



doesn’t run.

But you can use the to_a method to transform the ActiveRecord::NamedScope::Scope to an Array :

May 14, 2010
0 thanks

You must use the yielded object

A warning note (at least for v2.3.4): if you don’t use the yielded format object, you will get a cryptic error like this:

NoMethodError (You have a nil object when you didn't expect it!
The error occurred while evaluating nil.call):
 app/controllers/comments_controller.rb:11:in `create'

So make sure you use it!

May 11, 2010
1 thank

No Layout, other options

While it renders to the same rules as render, you need to specify params.

You’d think this would work:

render_to_string "users/profile", :layout => false

You need to do this instead

render_to_string(:layout => "users/profile", :layout => false)
May 6, 2010
1 thank


Be aware that has_and_belongs_to_many saves association to join table immediately after assign. It does NOT wait for my_object.save. Hence if save does not get through validations (or fail for any other reason), associated records will still be in the database.

Here is a nice workaround: http://github.com/TylerRick/has_and_belongs_to_many_with_deferred_save

May 4, 2010
0 thanks

Be careful about ActiveRecord::Base.include_root_in_json

If you have set ActiveRecord::Base.include_root_in_json = true, then when you do .to_json on an object, the output will begin with the class name rather than just a hash of attributes.

from the rails docs

konata = User.find(1)
ActiveRecord::Base.include_root_in_json = true
=> { "user": {"id": 1, "name": "Konata Izumi", "age": 16,
          "created_at": "2006/08/01", "awesome": true} }

if you try to pass this output as the argument to from_json, things will blow up.

User.new.from_json(konata.to_json[“user”]) will just pass in the attribute hash and will work.

Also, note that if you’ve use attr_accessible to limit mass assignment, you’ll have problems if you try pass in attributes that are not allowed to be mass assigned.

April 27, 2010
0 thanks

smtp syntax error 555 5.5.2

If You’re seeing a Net::SMTPFatalError (555 5.5.2 Syntax error ...) than You should check the email’s from header ! You probably have brackets while calling the from attribute setter :

Works in Rails < 2.3.3

def signup_notification(recipient)
  recipients      recipient.email_address_with_name
  subject         "New account information"
  from            %("My App" <no-reply@myapp.com>)

Works in Rails 2.3.5

def signup_notification(recipient)
  recipients      recipient.email_address_with_name
  subject         "New account information"
  from            'no-reply@myapp.com' # no <> brackets !

in Rails 2.3.3 the from email address will get wrapped with angle brackets, thus it must not have them within the address.

April 25, 2010
0 thanks

Avoid DoubleRenderError

One can not invoke render twice during an action. Thus if You have a complicated rendering logic but at the end would like to render some default content, or just would like to find out whether render has been called during the current action, use performed?. This also works with “empty” renderings such as head.

April 24, 2010
0 thanks

Rendering After Exception In respond_to() Block

Remember, format blocks set the response’s content type. This can present problems when handling errors.

class MediaController
  rescue_from  ActionController::MissingFile do |e|
    # User's browser probably wont display this 
    # Content-Type is application/x-shockwave-flash
    render :file => File.join(Rails.public_path, '404.html'), :status => 404 

  # show details or stream video
  def show
    @media = Media.find params[:id]
    respond_to do |format|
      format.flv { send_file @media.path, :disposition => 'inline' }

For these situations you must set :content_type when calling render:

render :file => File.join(Rails.public_path, '404.html'), :status => 404, :content_type => 'text/html' 
April 22, 2010
1 thank

Dynamic exists? methods

There are no dynamic exists? methods analogous to dynamic finders, which means that while you can do this:


you can’t do this:

Person.exists_by_name('David') # DOES NOT WORK

nor this:

Person.exists_by_name?('David') # DOES NOT WORK

However, you can simulate this with dynamic scope:


You’ll have to admit that this is so much better than the plain old method:

Person.exists?(:name => "David")
April 22, 2010
1 thank

nil Argument Raises An I18n::ArgumentError

You might want to do this:

module ActionView
 module Helpers
   module TranslationHelper
     def localize(*args)
       #Avoid I18n::ArgumentError for nil values
       I18n.localize(*args) unless args.first.nil?
     # l() still points at old definition
     alias l localize


April 20, 2010
2 thanks

Does not work with polymorphic relations

If you have polymorphic relations, e.g.:

class Bookmark < ActiveRecord::Base
  belongs_to :thing, :polymorphic => true
  belongs_to :owner, :polymorphic => true

and you want to ensure that a thing can bookmarked by an owner at most once, you can’t do this:

validates_uniqueness_of :thing, :scope => :owner

Instead, you must use the real column names, e.g.:

validates_uniqueness_of :thing_id, :scope => [:thing_type, :owner_id, :owner_type]
April 9, 2010
2 thanks

The :method goes in the :html option

When using a restful form helper and you want to use a method other than POST, remember to put the :method in the :html option.

e.g. To send a DELETE request instead of the usual POST (with a nested resource thrown in for good measure) use:

<% form_for [@post, @comment], :html => { :method => :delete } do |f| -%>
April 3, 2010
0 thanks

:autosave => false vs. :autosave => nil

The documentation above mentions that :autosave => true always saves the association and that it’s “off” by default. What it doesn’t mention what they mean by “off”.

  • :autosave => nil (the default “off” behavior) will still autosave the association if it has changed or is a new record.

  • :autosave => false seems to prevent autosaving of the association, even if it has changed.

I’ve found :autosave => false to be useful behavior when trying to prevent cyclical dependency loops; there are likely other useful use cases out there.

April 3, 2010 - (>= v2.2.1)
3 thanks

Careful with this method.

Despite the name and description, it will actually update any changed fields on the model rather than just the desired attribute.

def update_attribute(name, value)
  send(name.to_s + '=', value)

See? Use update_all and pass in the model ID as a condition, instead.

April 1, 2010
0 thanks

Fetching records when column is set to nil or false

If you want to fetch all records when one column (boolean) is set to nil or false, try this:

Project.all(:conditions => "archived IS NULL OR archived = 'f'")
March 31, 2010
0 thanks

Always gracefully degrade if JS isn't available

If you always want to degrade when JS isn’t available you can add something like to environment.rb

module ActionView
  module Helpers
    module PrototypeHelper
      def link_to_remote(name, options = {}, html_options = nil)
         html_options ||= {}
         html_options[:href] ||= options[:url]
         link_to_function(name, remote_function(options), html_options || options.delete(:html))
March 29, 2010
0 thanks

Wrong example

In the authentication filter example above, the time condition should be reversed: we only want to find the user if time is still in the future (because it’s the valid-until time).

So the example should look like this:

id, time = @verifier.verify(cookies[:remember_me])
if time > Time.now
  self.current_user = User.find(id)
March 25, 2010
0 thanks

How to test callback methods

When testing callback methods, try to test the callback chain separate from its implementation.

Say this is your model:

class Project

  belongs_to :owner
  has_many :milestones

  after_save :create_milestones
  after_save :notify_owner


  def notify_owner

  def create_milestones
    milestones.create(:name => 'Milestone 1')


You should write your spec like this:

describe Project do

  describe 'create_milestones' do
    it 'should create an initial milestone' do
      project = Project.new

  describe 'notify_owner' do
    it 'should notify its owner' do
      project = Project.new(:owner => mock_model(User))

  describe 'after_save' do
    it 'should run the proper callbacks' do
      project = Project.new


Here is some more advice on how to test callback methods in Rails:


March 25, 2010
0 thanks

Using models in your migration

Here is some advice how to call your models in a migration without shooting yourself in the foot:


Basically you can inline models into your migrations to decouple them from changes in your model:

class AddCurrentToVendor < ActiveRecord::Migration

  class Vendor < ActiveRecord::Base

  class Article < ActiveRecord::Base
    has_many :vendors, :class_name => 'AddCurrentToVendor::Vendor', :order => 'created_at'

  def self.up
    add_column :vendors, :current, :boolean
    Article.all.each do |article|
      article.vendors.first.andand.update_attribute(:current, true)

  def self.down
    remove_column :vendors, :current
March 25, 2010
0 thanks

How to test custom error pages

Here is some advice for testing custom error pages using Webrat and Cucumber:


March 24, 2010
1 thank

Setting primary key from hash

If you try to specify the value for your primary key (usually “id”) through the attributes hash, it will be stripped out:

Post.new(:id => 5, :title => 'Foo') #=> #<Post @id=nil @title="Foo">

You can solve this by setting it directly, perhaps by using a block:

Post.new(:title => "Foo") { |p| p.id = 5 } #=> #<Post @id=5 @title="Foo">

This behavior is something you’d probably only have a problem with when you have custom primary keys. Perhaps you have a User model with a primary key of “name”…

class User < ActiveRecord::Base
  set_primary_key :name

User.new(params[:user]) # This will never work

You can solve this on a case-to-case basis by calling attributes= directly with the “ignore protected” option:

User.new { |user| user.send(:attributes=, params[:user], false) } # BAD BAD BAD!

You should not do the above example, though. If you do, all protected attributes are ignored, which is very, very bad when you only care about the primary key.

I’d recommend one of the following instead:

# Option 1 – Always allow primary key. Avoid with models created by users
class User
    def attributes_protected_by_default
      super - [self.class.primary_key.to_s]

# Option 2 – Add a new method for this case
class User
  def self.new_with_name(attributes = nil)
    new(attributes) { |u| u.name = attributes[:name] }

As always when something is hard to do in Rails: Think about your design? Is it recommended? Is it sound? Do you really need to have a custom primary key?

March 23, 2010
1 thank

named_scopes and Acts as State Machine

As of AASM 2.1 named_scope(s) are defined by default for each state of a model.

March 19, 2010
1 thank

singular_class_name method missing

If this method is undefined in ActionView::Base, add to your ApplicationController:

class ApplicationController < ActionController::Base
  helper_method :singular_class_name
March 17, 2010
0 thanks


out of the box touch will run with validations

March 16, 2010 - (>= v2.2.1)
0 thanks



ActionController::AbstractRequest.relative_url_root= "/exampleapp"


config.action_controller.relative_url_root= "/exampleapp"
March 13, 2010
3 thanks

Can be used with has_many associations

You can also use this to validate that a has_many association has a specified number of records on the other end:

has_many :members

validates_length_of :members, :minimum => 1
March 11, 2010
1 thank

Skips validations and callbacks

The method skips validations and callbacks. That is why it should be used with caution.

Code example

person.toggle :active