Forum: Ruby on Rails validates_uniqueness_of with a condition

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
6992e8171ed4afa8b4ad4a8cef31fa29?d=identicon&s=25 Enrico Teotti (Guest)
on 2006-05-12 10:32
(Received via mailing list)
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
9d1f5d2d9de70bd9a934f557dc95a406?d=identicon&s=25 Daniel ----- (liquid)
on 2006-05-12 13:22
(Received via mailing list)
Hi Enrico,

What do you mean you want to have it unique to a given year?  I that
with
some other criteria as well?
2b891e820c238ded365d035771603f21?d=identicon&s=25 Bill Walton (Guest)
on 2006-05-12 14:29
(Received via mailing list)
Hi Enrico,

Enrico Teotti 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
6992e8171ed4afa8b4ad4a8cef31fa29?d=identicon&s=25 Enrico Teotti (Guest)
on 2006-05-12 15:08
(Received via mailing list)
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
2b891e820c238ded365d035771603f21?d=identicon&s=25 Bill Walton (Guest)
on 2006-05-12 15:52
(Received via mailing list)
Enrico Teotti 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.
<snip>

> 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
This topic is locked and can not be replied to.