validates_uniqueness_of across multiple rows?

Ok, that's not the best subject line, but I couldn't think of a concise way to describe what I'm trying to do.

I've got two models. Grouping simply contains an id and a few other attributes (e.g. rating). A grouping can contain many elements which are stored the Element model.

A set of elements is tied together by a grouping_id. An element can be one of several types of objects. I'm doing this with polymorphic associations.

I need a way to ensure that a grouping is unique. That is, there should not be two grouping_ids containing the exact same elements.

The closest analogy I can think of is a composite primary key. Except, this is across multiple rows (instead of columns) and uses polymorphic association types and ids.

Can this be easily done with Rails and ActiveRecord?

Thanks, Raj

raji wrote: [...]

I need a way to ensure that a grouping is unique. That is, there should not be two grouping_ids containing the exact same elements.

The closest analogy I can think of is a composite primary key. Except, this is across multiple rows (instead of columns) and uses polymorphic association types and ids.

Can this be easily done with Rails and ActiveRecord?

Well, you could write a custom validator, something like (untested): class Grouping < AR::B   validate :must_have_unique_elements

  def must_have_unique_elements     taken = (elements.first.groupings.find :element_ids => element_ids).empty?     # There's gotta be a more efficient way to write that query.

    errors.add_to_base("That combination of elements already exists!") if taken   end end

I don't think there's anything off the shelf to make this easier, but I might be wrong...

Thanks, Raj

Best,

This isn't something that's going to be easy in any ORM, but here's an idea.

What about caching a list of the members of a Grouping in an attribute? You'd need to include the type obviously, so it would look something like this:

'bar:1,bar:5,foo:2,frob:14'

You'd need to update this field when adding an element, and then validates_uniqueness_of and/or unique key it in the DB.

Also note that you'll want to sort it, otherwise you'll run into problems.

Dealing with users concurrently adding things to Groupings is a whole 'nother bucket of hurt, which will be trickier to deal with.

--Matt Jones