Reputation: 5174
I'm working on a site designed for sharing stories, as part of my efforts to learn Ruby on Rails. I've managed to get a lot of steps done, but I'm stuck on how to create a unique constraint across two properties of a model.
I was able to create a database-level uniqueness constraint, which should help there, but the 'rails way' says I need to create that in the model as well, that the database constraint is just a backup in case of parallelism issues (the classic 'user double clicked a button' scenario).
My problem could be considered equivalent to creating a second primary key, which happens to be a composite of two variables in the object. That said, I'm not actually interested in supplanting the 'natural' composite key, and would in fact be perfectly happy with leaving it in place. I prefer to use unique ID's to identify each object in a table for most situations.
That said, for the purposes of this app I need a way to define a uniqueness constraint across two columns. Stories can be duplicated, and chapter numbers can be duplicated, but you can never, ever duplicate a given chapter number for a given story. A story can have one and only one chapter one. Of course, just because it's numbered one doesn't mean it's titled chapter one; it could be prologue. Or Chapter Zero. Or whatever. This number is only used (or will be, once I get that far) to help create a 'clean' url. I don't mind the storyID being fairly high, or for a given set of stories to have non-sequential ID's. That's fine. But I think it would be confusing to the reader to see the url go from story/1/chapter/32 to story/1/chapter 512 when he goes from the first chapter of a story to the second.
I tried this:
validates [:story_id, :number], uniqueness:true
But it doesn't work -- it can't generate a symbol out of an array. So I don't know what to do from here.
Upvotes: 1
Views: 153
Reputation: 10630
validates :number, uniqueness: {scope: [:story_id]}
This will enforce uniqueness validation on number with story_id scope. That means that your numbers will be unique for a given story_id.
Upvotes: 7