Multiple scopes with validates_uniqueness_of in Rails

Previously, I talked about Validates_uniqueness_of and scope in rails

Well, what happens if you’ve got a case where, say you’re selling widgets, and you’ve got a join model set up with has_many :through relations, and you’re working with the following table:

(we’re listing stores that sell our widgets, and what size and price they sell them for)

Table: saleitems

Columns: widget_id, store_id, size, price

So, now, we want to validate that a widget can be sold at any store, and a widget can be sold many times at one store, but we can only sell a widget-store-size combo once. (You can’t sell a LARGE widget twice at the same store)

I think I was wrong, previously in my understanding. Now, I’ve written some code and see that you do the following:

You add a “validate_on_create” function to your saleitems model, and it looks like this:

def validate_on_create
   if Store.find_by_widget_id_and_size_and_store_id(widget_id, size, store_id)
   errors.add(‘you can’t do that’)

end

Thanks to: Rails Weenie for the answer

technorati tags:, , ,

Published by

matt

I'm a software engineer in New Orleans interested in making things, growing things, big fast computers, media convergence, and pugs.

-41 thoughts on “Multiple scopes with validates_uniqueness_of in Rails”

  1. After spending an hour or so googling for an answer, I decided to just try the equivalent of


    validates_uniqueness_of :widget_id, :scope => [:store_id, :size]
    validates_uniqueness_of :store_id, :scope => [:widget_id, :size]
    validates_uniqueness_of :size, :scope => [:store_id, :widget_id]

    and see if it worked. And for me, using a recent version of everything, it did.

    YMMV.

  2. I think that using validates_uniqueness_of :widget_id, :scope => [ :size, :store_id ] works just fine — but it seems to fail silently. Creating the validate_on_create function as you are showing would at least raise an error message.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>