Making validates_uniqueness_of case insensitive


#1

Hi, what is the easiest way to modify my model so that
“validates_uniqueness_of” is case insensitive? For example, I want a
user’s email address to be unique regardless of case.

thanks,
Jeff


#2

Specifically, for email addresses, the easiest way (though maybe not the
way you want to do it) is to upper or lower case it going into the
database! :wink: You probably are looking for a more elegant solution,
huh? This would only be good for email addresses - so perhaps someone
can give a better answer for other fields that would follow a similar
requirement.

Michael


#3

On 11/12/05, Jeff C. removed_email_address@domain.invalid wrote:

Hi, what is the easiest way to modify my model so that
“validates_uniqueness_of” is case insensitive? For example, I want a
user’s email address to be unique regardless of case.

It’s not the Rails way, but a unique index in the database will work.
For example, in PostgreSQL:

CREATE UNIQUE INDEX index_name ON table_name (lower(column_name));


#4

I don’t want to store the data as lower case. For example, login
names should also be unique regardless of case, but I want to
preserve the login name with its original casing.

So, it looks like I will have to create my own validation for now.
The question is whether I can mix my own validations with the other
existing standard validations (e.g.
“validates_presence_of :first_name”)?

-Jeff


#5

On 13-nov-2005, at 3:40, Jeff C. wrote:

Hi, what is the easiest way to modify my model so that
“validates_uniqueness_of” is case insensitive? For example, I want
a user’s email address to be unique regardless of case.

thanks,
Jeff

class Foo <AR::Base
before_validation :lowercase_email
private
def lowercase_email
email.downcase!
end
end
end


#6

On 13-nov-2005, at 14:52, Jeff C. wrote:

I don’t want to store the data as lower case. For example, login
names should also be unique regardless of case, but I want to
preserve the login name with its original casing.

So, it looks like I will have to create my own validation for
now. The question is whether I can mix my own validations with
the other existing standard validations (e.g.
“validates_presence_of :first_name”)?

Well, I don’t know what reason one would have to store mixed-case
logins (especially if you require logins to be
unique regardless of case) - but you also can try and
add :case_insensitive=>true to validations, make a unit test
and it will be part of Rails


#7

I’ve seen a need for it with checking for uniqueness in the names of a
set of things, eg ‘book’ vs ‘Book’, so I think it’s a valid request.

It seems to me that the default behaviour is left to the database
configuration.


#8

james.rw.walker wrote:

I’ve seen a need for it with checking for uniqueness in the names of a
set of things, eg ‘book’ vs ‘Book’, so I think it’s a valid request.

It seems to me that the default behaviour is left to the database
configuration.

Hi,

I dont know which version you use but validates_uniqueness_of if is case
insensitive. I just did a check, and it works fine for me.

S


#9

--------------- app/model/asset_type.rb:
class AssetType < ActiveRecord::Base
attr_accessible :name
has_many :asset
validates_length_of :name, :within => 1…100, :too_long => “pick a
shorter name”, :too_short => “pick a longer name”
validates_uniqueness_of :name, :message => “an asset type with that
name already exists”
end

--------------- test/unit/asset_type_test.rb:
require File.dirname(FILE) + ‘/…/test_helper’
class AssetTypeTest < Test::Unit::TestCase
def test_unique_name
newObj = AssetType.new( {:name => ‘test’} )
assert newObj.save, ‘Can save test the first time’
newObj = AssetType.new( {:name => ‘test’} )
assert !newObj.save, ‘Can not save a duplicate test’
newObj = AssetType.new( {:name => ‘Test’} )
assert newObj.save, ‘Can save Test vs test’
end
end


All tests pass, if it was case insensitive then the saving of ‘Test’
should fail.

As a side note - how can I catch the validation failure message in my
test?


actionmailer (1.1.1)
actionpack (1.10.1)
activerecord (1.12.1)
activesupport (1.2.1)
postgres-pr (0.4.0)
rails (0.14.1)


#10

On 11/14/05, James W. removed_email_address@domain.invalid wrote:

end
end


All tests pass, if it was case insensitive then the saving of ‘Test’
should fail.

As a side note - how can I catch the validation failure message in my test?

assert_equal(“an asset type with that
name already exists”, newObj.errors[:name])


Cheers,

Peter D.


#11

On Nov 14, 2005, at 3:50 AM, Sushruth blah wrote:

case
insensitive

No, it really isn’t. It’s really your DB that’s case insensitive.
Observe:

PostgreSQL:
template1=# select ‘foo’ = ‘Foo’;
?column?

f

SQLite:
sqlite> select ‘foo’ = ‘Foo’;
0

are both false, while MySQL:
mysql> select ‘foo’ = ‘Foo’;
±--------------+
| ‘foo’ = ‘Foo’ |
±--------------+
| 1 |
±--------------+


Scott B.
Lunchbox Software
http://lunchboxsoftware.com
http://lunchroom.lunchboxsoftware.com
http://rubyi.st