# Validates\_uniqueness\_of on massaged contents of column

**URL:** <https://www.ruby-forum.com/t/validates-uniqueness-of-on-massaged-contents-of-column/132291>\
**Category:** Rails\
**Created:** [March 18, 2008, 8:47pm UTC](https://www.ruby-forum.com/t/validates-uniqueness-of-on-massaged-contents-of-column/132291 "2008-03-18T20:47:19Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![byrnejb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/d2c977/32.png) [@byrnejb](https://www.ruby-forum.com/u/byrnejb)\
**Post date:** [March 18, 2008, 8:47pm UTC](https://www.ruby-forum.com/t/validates-uniqueness-of-on-massaged-contents-of-column/132291/1 "2008-03-18T20:47:19Z")

</div>

I am trying to check the uniqueness of a column updated from a form. In  
my model I have this:

class Entity \< ActiveRecord::Base

has\_one :client, :dependent =\> :destroy  
has\_many :sites, :through =\> :locations

before\_validation :indexed\_name

validates\_presence\_of :entity\_name  
validates\_presence\_of :entity\_legal\_name  
validates\_presence\_of :entity\_legal\_form

validates\_uniqueness\_of :entity\_name

def entity\_name  
read\_attribute(:entity\_name).titlecase  
end

def entity\_name=(name)  
write\_attribute(:entity\_name, name.keycase)  
end

def indexed\_name  
self.entity\_name = self.entity\_name.keycase  
end

(keycase is a local extension to the string class)

This code coerces the values entered into entity\_name to lowercase and  
saves them to the database and displays data in that column as  
titlecase. All that works as expected. What does not work is the  
validates\_uniqueness\_of.

What I desire is that form data entered into entity\_name as “A TEST  
CLIENT” be massaged to “a test client” BEFORE the  
validates\_uniqueness\_of is performed. This is not what is happening  
even though the update SQL is generated with the contents of entity\_name  
properly prepared.

How do I accomplish this?

---

<div class="post-metadata">

**Author:** ![byrnejb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/d2c977/32.png) [@byrnejb](https://www.ruby-forum.com/u/byrnejb)\
**Post date:** [March 18, 2008, 11:45pm UTC](https://www.ruby-forum.com/t/validates-uniqueness-of-on-massaged-contents-of-column/132291/2 "2008-03-18T23:45:51Z")

</div>

Try setting up a call back on the model that runs before validation:

before\_validation()

> **[ActiveRecord::Callbacks](https://api.rubyonrails.org/classes/ActiveRecord/Callbacks.html#M001303)**
>
> Active Record Callbacks Callbacks are hooks into the life cycle of an Active Record object that allow you to trigger logic before or after a change in the object state.

On Mar 18, 12:47 pm, James B. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

---

<div class="post-metadata">

**Author:** ![byrnejb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/d2c977/32.png) [@byrnejb](https://www.ruby-forum.com/u/byrnejb)\
**Post date:** [March 19, 2008, 1:56am UTC](https://www.ruby-forum.com/t/validates-uniqueness-of-on-massaged-contents-of-column/132291/3 "2008-03-19T01:56:15Z")

</div>

removed\_email\_address@domain.invalid wrote:

> Try setting up a call back on the model that runs before validation:
> 
> before\_validation()
> 
> [ActiveRecord::Callbacks](http://api.rubyonrails.org/classes/ActiveRecord/Callbacks.html#M001303)

I have done that:

before\_validation :indexed\_name

validates\_uniqueness\_of :entity\_name

def indexed\_name  
self.entity\_name = self.entity\_name.keycase  
end

And this does not work. What variable contains the value that is used  
by validates\_uniqueness\_of?

Oh, by the way, I found this tonight. Apparently I am not the only one  
twisting in the wind on this problem.

[http://blog.craz8.com/articles/2007/12/10/rails-validates\_uniqueness\_of-is-completely-broken/](http://blog.craz8.com/articles/2007/12/10/rails-validates_uniqueness_of-is-completely-broken/)

---

<div class="post-metadata">

**Author:** ![byrnejb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/d2c977/32.png) [@byrnejb](https://www.ruby-forum.com/u/byrnejb)\
**Post date:** [March 19, 2008, 2:38am UTC](https://www.ruby-forum.com/t/validates-uniqueness-of-on-massaged-contents-of-column/132291/4 "2008-03-19T02:38:27Z")

</div>

This is the development log:

Processing EntitiesController#new (for 127.0.0.1 at 2008-03-18 21:23:11)  
[GET]  
Session ID:  
BAh7BzoMY3NyZl9pZCIlMjFkMjZlMWE3ODgyM2MwMzBmZmE0NzJiMzI2OGJl%0ANjYiCmZsYXNoSUM6J0FjdGlvbkNvbnRyb2xsZXI6OkZsYXNoOjpGbGFzaEhh%0Ac2h7AAY6CkB1c2VkewA%3D–2c65e7445b0b3a4500a926ab4ca20ba2d50b06d1  
Parameters: {“action”=\>“new”, “controller”=\>“entities”}  
Entity Indexes (0.000000) PRAGMA index\_list(entities)  
SQL (0.000000) PRAGMA index\_info(‘idxU\_entities\_entity\_name’)  
Rendering template within layouts/entities  
Rendering entities/new  
Completed in 0.04700 (21 reqs/sec) | Rendering: 0.01600 (34%) | DB:  
0.00000 (0%) | 200 OK [[http://localhost/entities/new](http://localhost/entities/new)]

Processing ApplicationController#index (for 127.0.0.1 at 2008-03-18  
21:23:11) [GET]  
Session ID:  
BAh7BzoMY3NyZl9pZCIlMjFkMjZlMWE3ODgyM2MwMzBmZmE0NzJiMzI2OGJl%0ANjYiCmZsYXNoSUM6J0FjdGlvbkNvbnRyb2xsZXI6OkZsYXNoOjpGbGFzaEhh%0Ac2h7AAY6CkB1c2VkewA%3D–2c65e7445b0b3a4500a926ab4ca20ba2d50b06d1  
Parameters: {}

…

Submit new data.

Processing EntitiesController#create (for 127.0.0.1 at 2008-03-18  
21:23:51) [POST]  
Session ID:  
BAh7BzoMY3NyZl9pZCIlMjFkMjZlMWE3ODgyM2MwMzBmZmE0NzJiMzI2OGJl%0ANjYiCmZsYXNoSUM6J0FjdGlvbkNvbnRyb2xsZXI6OkZsYXNoOjpGbGFzaEhh%0Ac2h7AAY6CkB1c2VkewA%3D–2c65e7445b0b3a4500a926ab4ca20ba2d50b06d1  
Parameters: {“commit”=\>“Create”, “entity”=\>{“entity\_legal\_name”=\>“The  
Second should fail Test Client Ltd.”, “entity\_name”=\>“second test  
client”, “entity\_legal\_form”=\>“CORP”},  
“authenticity\_token”=\>“1de43991e546d4823d88635f1971041ba746b432”,  
“action”=\>“create”, “controller”=\>“entities”}  
Entity Indexes (0.000000) PRAGMA index\_list(entities)  
SQL (0.000000) PRAGMA index\_info(‘idxU\_entities\_entity\_name’)

THIS is the validation call:

Entity Load (0.000000) SELECT \* FROM entities WHERE  
(entities.entity\_name = ‘Second Test Client’) LIMIT 1

Why is “entity\_name”=\>“second test client” in the parameters passed  
above but entities.entity\_name is nonetheless set equal to ‘Second Test  
Client’? What variable is holding this value?

The code for validated\_uniqueness\_of is

510: def validates\_uniqueness\_of(\*attr\_names)  
511: configuration = { :message =\>  
ActiveRecord::Errors.default\_error\_messages[:taken] }  
512: configuration.update(attr\_names.pop) if  
attr\_names.last.is\_a?(Hash)  
513:  
514: validates\_each(attr\_names,configuration) do |record,  
attr\_name, value|  
515: condition\_sql = “#{record.class.table\_name}.#{attr\_name}  
#{attribute\_condition(value)}”  
516: condition\_params = [value]  
517: if scope = configuration[:scope]  
518: Array(scope).map do |scope\_item|  
519: scope\_value = record.send(scope\_item)  
520: condition\_sql \<\< " AND  
#{record.class.table\_name}.#{scope\_item}  
#{attribute\_condition(scope\_value)}"  
521: condition\_params \<\< scope\_value  
522: end  
523: end  
524: unless record.new\_record?  
525: condition\_sql \<\< " AND  
#{record.class.table\_name}.#{record.class.primary\_key} \<\> ?"  
526: condition\_params \<\< record.send(:id)  
527: end  
528: if record.class.find(:first, :conditions =\>  
[condition\_sql, \*condition\_params])  
529: record.errors.add(attr\_name, configuration[:message])  
530: end  
531: end  
532: end

What is passing |value| from the model? This seems to be the source of  
the difficulty.

---

<div class="post-metadata">

**Author:** ![byrnejb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/d2c977/32.png) [@byrnejb](https://www.ruby-forum.com/u/byrnejb)\
**Post date:** [March 19, 2008, 7:15pm UTC](https://www.ruby-forum.com/t/validates-uniqueness-of-on-massaged-contents-of-column/132291/5 "2008-03-19T19:15:08Z")

</div>

@James:

The answer is in the code you’re written.

def entity\_name  
read\_attribute(:entity\_name).titlecase  
end

def entity\_name=(name)  
write\_attribute(:entity\_name, name.keycase)  
end

You’ve provided an accessor for ‘entity\_name’ that reads the attribute  
and returns it in titlecase form. That would appear to explain why  
you’re getting ‘Second Test Client’ – you’re going through the  
accessor which is doing what you’ve asked it.

On Mar 18, 9:38 pm, James B. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)
