# Validates\_uniqueness\_of with a condition

**URL:** <https://www.ruby-forum.com/t/validates-uniqueness-of-with-a-condition/60340>\
**Category:** Rails\
**Created:** [May 12, 2006, 10:32am UTC](https://www.ruby-forum.com/t/validates-uniqueness-of-with-a-condition/60340 "2006-05-12T10:32:37Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![eno](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/f1d935/32.png) [@eno](https://www.ruby-forum.com/u/eno)\
**Post date:** [May 12, 2006, 10:32am UTC](https://www.ruby-forum.com/t/validates-uniqueness-of-with-a-condition/60340/1 "2006-05-12T10:32:37Z")

</div>

Hi,  
I need to check the uniqueness of an attribute (a doc number) using a  
condition (a specific year), I’ve found validates\_uniqueness\_of  
:number, but I need to tell it I just want to check a specific year.  
I’ve found :scope but I haven’t really understood it’s meaning, Can I  
scope on a specific year?  
Thanks,  
Enrico

–  
“The only thing necessary for the triumph of evil  
is for good men to do nothing”  
Edmund Burke

---

<div class="post-metadata">

**Author:** ![eno](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/f1d935/32.png) [@eno](https://www.ruby-forum.com/u/eno)\
**Post date:** [May 12, 2006, 1:22pm UTC](https://www.ruby-forum.com/t/validates-uniqueness-of-with-a-condition/60340/2 "2006-05-12T13:22:28Z")

</div>

Hi Enrico,

What do you mean you want to have it unique to a given year? I that  
with  
some other criteria as well?

---

<div class="post-metadata">

**Author:** ![eno](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/f1d935/32.png) [@eno](https://www.ruby-forum.com/u/eno)\
**Post date:** [May 12, 2006, 2:29pm UTC](https://www.ruby-forum.com/t/validates-uniqueness-of-with-a-condition/60340/3 "2006-05-12T14:29:14Z")

</div>

Hi Enrico,

Enrico T. wrote:

> I need to check the uniqueness of an attribute (a doc number) using a  
> condition (a specific year), I’ve found validates\_uniqueness\_of  
> :number, but I need to tell it I just want to check a specific year. I’ve  
> found :scope but I haven’t really understood it’s meaning, Can I  
> scope on a specific year?

The scope parameter allows you to verify uniqueness within a subset of  
the  
records in a table. If we assume a table definition as follows…

create table docs;  
id int not null auto\_increment,  
doc\_num int,  
year date,  
primary key (id)  
);

then including

validates\_uniqueness\_of :doc\_num, :scope =\> “year”

in your doc model will allow you to enter:

doc\_num = ‘1’ year = ‘2000’  
doc\_num = ‘2’ year = ‘2000’  
doc\_num = ‘1’ year = ‘2001’  
doc\_num = ‘2’ year = ‘2001’  
etc.

but will not allow any duplicates of these entries.

hth,  
Bill

---

<div class="post-metadata">

**Author:** ![eno](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/f1d935/32.png) [@eno](https://www.ruby-forum.com/u/eno)\
**Post date:** [May 12, 2006, 3:08pm UTC](https://www.ruby-forum.com/t/validates-uniqueness-of-with-a-condition/60340/4 "2006-05-12T15:08:32Z")

</div>

the target is to check on document update, not to choose an already  
used number. Numbers restart from 1 at the end of the year… so I  
also need to specify an year.  
First of all I need to know if the number is beeing changed. Then I’ll  
check if the new number isn’t already used in the current year.  
Right now I’ve used this way:  
def validate\_on\_update  
exist = Document.find(:first, :conditions =\> “type =  
‘#{self.type}’ AND extract(year from created\_at) = #{Time.now.year}  
AND number = #{self.number} AND id != #{self.id}”)  
if exist  
errors.add\_to\_base(“I can’t update the doc with this number!”)  
end  
end  
this is kinda uggly cz I always query the DB,  
I guess I could control with a before\_filter (of before something I  
forgot) if the new value is different than the old one. Then query the  
DB.  
Anyway…

> in your doc model will allow you to enter:
> 
> doc\_num = ‘1’ year = ‘2000’  
> doc\_num = ‘2’ year = ‘2000’  
> doc\_num = ‘1’ year = ‘2001’  
> doc\_num = ‘2’ year = ‘2001’  
> etc.
> 
> but will not allow any duplicates of these entries.  
> so my guess was right, the point is I don’t have a column year, I have  
> a created\_at datetime column. Can I estrapolate the year and put it in  
> the scope?  
> I’ve tried putting the psql extract(year from created\_at) within  
> scope but it didn’t worked…  
> maybe I’ll try to create a “fake” method called year based on the  
> record datestamp…

–  
“The only thing necessary for the triumph of evil  
is for good men to do nothing”  
Edmund Burke

---

<div class="post-metadata">

**Author:** ![eno](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/f1d935/32.png) [@eno](https://www.ruby-forum.com/u/eno)\
**Post date:** [May 12, 2006, 3:52pm UTC](https://www.ruby-forum.com/t/validates-uniqueness-of-with-a-condition/60340/5 "2006-05-12T15:52:08Z")

</div>

Enrico T. wrote:

> the target is to check on document update, not to choose an already used  
> number. Numbers restart from 1 at the end of the year… so I  
> also need to specify an year.

> so my guess was right, the point is I don’t have a column year, I have a  
> created\_at datetime column. Can I estrapolate the year and put it in the  
> scope?

Yes, you will need a column for just the year and yes, you can extract  
that  
from the created\_at column if you want / need to. If you’re dealing  
with an  
existing database, I’d probably do the extraction as part of a  
migration.  
After the initial migration, I’d put the code to populate the year  
column in  
the controller rather than muddying up the model, but I imagine either  
will  
work. Once you have a table with the year column populated for all the  
records in it, the 'validates\_uniqueness\_of :doc\_num, :scope =\> “year” ’  
validation will do what you’re looking for.

Best regards,  
Bill
