Consider this bit of code:
## News model
class News < ActiveRecord::Base
before_create :validate_date
def validate_date
raise "Invalid creation date..." if created_on > Time.now
end
end
##News controller
class Publish::NewsController < Publish::BaseController
def create
begin
@news = News.new(params[:news])
rescue
flash[:notice] = "Invalid creation date"
render :action => 'new'
end
if @news.save
flash[:notice] = 'News was successfully created.'
redirect_to :action => 'list'
else
render :action => 'new'
end
end
end
… I’m well off here, I know. When date validation fails I see a RuntimeError in the controller and the string specified in the News.validate_date method.
Can someone explain how to properly deal with raising exceptions in the model and rescuing in the controller? Much appreciated…
You’re taking the right approach to rescuing exceptions however you are taking the wrong approach to your validations by using exceptions.
Rails already has a built-in mechanism for dealing with whether or not a record is a valid so instead of raising an exception what you should be doing is adding your error to the errors array. This will make @yourobject.valid? and @yourobject.save return false.
Theres also no need to set the validation method as a callback as Rails already has validation hooks you can tie into. So you should do something like this:
class News < ActiveRecord::Base
protected
def validate
self.errors.add(:created_on, "is invalid") if self.created_on > Time.now
end
end
class Publish::NewsController < Publish::BaseController
def create
@news = News.new(params[:news])
if @news.save
flash[:notice] = 'News was successfully created.'
redirect_to :action => 'list'
else
flash[:error] = @news.errors
render :action => 'new'
end
end
end
More information on Rails errors and validations:
http://api.rubyonrails.org/classes/ActiveRecord/Errors.html
Cheers thanks for that, Luke.