Jamie Gaskins

Ruby/Rails developer, coffee addict

Rails Scaffolded Create Is Wrong

Published Feb 26, 2012

A lot of developers have gotten used to the "Rails scaffold" method of saving and loading data inside their controllers. This is roughly what happens in about 95% of #create actions:

def create
  @article = Article.new(params[:article])

  if @article.save
    redirect_to @article, notice: 'Article saved.'
  else
    render :new
  end
end

Why I disagree with this

An if statement should imply that both methods are somewhat expected, but the only reason it'll hit the else clause is if the object is invalid. You shouldn't be expecting an invalid object. The expected outcome of this action is that it creates a record in the database. That is its only function. That is where it gets its name. Being passed an invalid object is an exception and should be treated as such.

ActiveRecord (and similar ORMs like Mongoid) provide a #save! method that raises an exception when the object is invalid. My objections to that particular name scheme aside — in Ruby, convention is that bang methods modify the object in place rather than return a copy with a modified value — this should be the default behavior of the #save method.

def create
  @article = Article.create(params[:article])
  redirect_to @article, notice: 'Article saved.'
rescue ActiveRecord::RecordNotSaved
  render :new
end

This makes more sense.

TwitterGithubRss