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?
--
Posted via http://www.ruby-forum.com/.
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Ruby on Rails: Talk" group.
To post to this group, send email to
rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
To unsubscribe from this group, send email to
rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
For more options, visit this group at
http://groups.google.com/group/rubyonrails-talk?hl=en
-~----------~----~----~----~------~----~------~--~---
ESPNDev-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org
2008-Mar-18 22:44 UTC
Re: validates_uniqueness_of on massaged contents of column
Try setting up a call back on the model that runs before validation: before_validation() http://api.rubyonrails.org/classes/ActiveRecord/Callbacks.html#M001303 On Mar 18, 12:47 pm, James Byrne <rails-mailing-l...-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> wrote:> 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? > -- > Posted viahttp://www.ruby-forum.com/.--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe@googlegroups.com For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
James Byrne
2008-Mar-19 00:56 UTC
Re: validates_uniqueness_of on massaged contents of column
ESPNDev-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org wrote:> Try setting up a call back on the model that runs before validation: > > before_validation() > > http://api.rubyonrails.org/classes/ActiveRecord/Callbacks.html#M001303I 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/ -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
James Byrne
2008-Mar-19 01:38 UTC
Re: validates_uniqueness_of on massaged contents of column
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]
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.
--
Posted via http://www.ruby-forum.com/.
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Ruby on Rails: Talk" group.
To post to this group, send email to
rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
To unsubscribe from this group, send email to
rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
For more options, visit this group at
http://groups.google.com/group/rubyonrails-talk?hl=en
-~----------~----~----~----~------~----~------~--~---
@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 Byrne
<rails-mailing-l...-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org>
wrote:> 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]
>
> 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.
> --
> Posted viahttp://www.ruby-forum.com/.
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Ruby on Rails: Talk" group.
To post to this group, send email to
rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
To unsubscribe from this group, send email to
rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
For more options, visit this group at
http://groups.google.com/group/rubyonrails-talk?hl=en
-~----------~----~----~----~------~----~------~--~---