Validates_uniqueness_of and combo of three fields

I have a model, Property, that has_many_polymorphs. The associated join
table (labellings) has fields:
id (simple record id),
property_id,
labellable_id
labellable_type.

It’s basically the same system used with acts_as_taggable, except that
Property objects are a tree instead of a simple list (which doesn’t have
any bearing on this problem, i think).

If i add a property to an object then a join table entry is created. If
i add it again, i now have the object labelled twice with the same
property, which i don’t want. I could say

object.properties << prop unless object.properties.include? prop

But that’s a bit cumbersome.

Ideally i’d use validates_uniqueness_of - i know that i can do this for
a combo of two values, with, eg

validates_uniqueness_of :property_id, :scope => :labellable_id

But i don’t know how to do it for three fields. I tried this:

validates_uniqueness_of :property_id, :scope => [:labellable_id,
:labellable_type]

but got this exception when i tested it:
ActiveRecord::RecordInvalid: Validation failed: Property has already
been taken

Anyone know how to do this?

thanks
max

Actually my syntax (validates_uniqueness_of :property_id, :scope =>
[:labellable_id, :labellable_type]) is correct, but i want it to simply
fail to save, rather than raise an exception. Does anyone know how to
do this?

Max W. wrote:

Actually my syntax (validates_uniqueness_of :property_id, :scope =>
[:labellable_id, :labellable_type]) is correct, but i want it to simply
fail to save, rather than raise an exception. Does anyone know how to
do this?

instead of model.save! or model.update!, use the form

if model.save

my model was saved successfully

else

my model didn’t save

end

also note

model.valid?

model.errors

hth

ilan

instead of model.save! or model.update!, use the form

if model.save

my model was saved successfully

else

my model didn’t save

end

Thanks Ilan - i played around with this a bit more and narrowed my
problem down a bit. It’s actually only the << (push) operator that
breaks horribly - save just quietly fails, which is what i want. So, as
a way of adding a label (join table entry) to an object (eg of class
Lesson) this works fine (ie fails without raising):

Label.create(:property_id => @prop.id, :labellable_id => @object.id,
:labellable_type => @object.class.to_s)

However, it’s a bit clunky. I’d rather just write

@prop.lessons << @object

But this does raise when it fails, ie if the join table entry exists
already.

I can sort of get around it by doing

@prop.lessons << @object rescue false

but it would be nice to not have to do that. I guess my problem is just
with the << method. Any ideas?

thanks
max