Note that there are some explanatory texts on larger screens.

plurals
  1. PORails 3: Handling exceptions from the DB adapter in ActiveRecord models
    primarykey
    data
    text
    <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>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload