title: Rails 3: Handling exceptions from the DB adapter in ActiveRecord models
body: <p>Here's what I'm trying to do; I thought this to be a common problem, but somehow I couldn't find any related topics...</p>
  
  <p>I have a model with a scoped uniqueness constraint. I've decided to do this by defining a unique index on the table in the migration, like so:</p>
  
  <pre><code>class CreateLossRatios &lt; ActiveRecord::Migration
    def up
      ...
      add_index :loss_ratios, [ :tool_id, :ends_at ], :unique =&gt; true
    end
  
    def down
      ...
    end
  end
  </code></pre>
  
  <p>This make ActiveRecord throw an exception when trying to save a record violating the index uniqueness. Now I want to make it appear as a validation error. I thought that the best way would be to catch ActiveRecord::RecordNotUnique right in the LossRatio model and populate the errors hash with a meaningful message. I've done it like that:</p>
  
  <pre><code>class LossRatio &lt; ActiveRecord::Base
    belongs_to :tool
  
    validates :rate, :ends_at, :tool, :presence =&gt; true
    validates_numericality_of :rate
    validates_inclusion_of :rate, :in =&gt; (0..1)
  
    %w{ create save }.each do |name|
      %W{ #{name} #{name}! }.each do |method|
        define_method(method) do |*args|
          begin
            super(*args)
          rescue ActiveRecord::RecordNotUnique =&gt; ex
            self.errors.add(:ends_at, I18n.t('activerecord.errors.models.loss_ratio.attributes.ends_at.not_unique'))
          end
        end
      end
    end
  
  end
  </code></pre>
  
  <p>This works, but seems a bit cumbersome. I understand that I'm making assumptions here (i.e. what happens if I add another DB level uniqueness constraint etc), but I don't see a way around this. Is there a more elegant solution / best practice when dealing with such scenarios?
  One alternative I can think of is using rescue_from, but I don't wanna do this, since </p>
  
  <ul>
  <li>I don't think this logic belongs in a controller, I want to make it transparent to the application logic</li>
  <li>most likely there will be no associated controller (these objects will be created solely as associations through another model), which makes it even more wrong from my point of view.</li>
  </ul>
  
  <p>Is there a way to make this model rescue from an exception thrown from any instance method? I've tried using a class level rescue clause, but it doesn't catch anything.</p>
  
  <hr>
  
  <p>Another question is whether I should still use AR scoped validation for ends_at. Even with RecordNotUnique handled, the object will still consider itself valid and have its timestamps set after an unsuccessful save attempt. Can it cause any unwanted side effects?</p>