I have this in a model validates_uniqueness_of :aspect, :scope => :user_id In an instance method of the same model I have "save!" but I don''t touch the :aspect attribute in that instance method at all. Whenever that save! command is run however I get this error: ActiveRecord::RecordInvalid: Validation failed: Aspect has already been taken I don''t understand. The validation should not skip the instance from which the method is called. Please help. Thanks. -- Posted via http://www.ruby-forum.com/.
Sorry, I meant The validation should SKIP the instance from which the method is called. It appears that save! tries to validate the object against itself and fails because of course it is not unique from itself. -- Posted via http://www.ruby-forum.com/.
Can you please explain why you think the validation should be "skipped"? Cheers, Nicholas On Jul 4, 5:59 am, Learn by Doing <rails-mailing-l...-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> wrote:> Sorry, I meant The validation should SKIP the instance from which the > method is called. It appears that save! tries to validate the object > against itself and fails because of course it is not unique from itself. > -- > Posted viahttp://www.ruby-forum.com/.
Hi Nicholas, Thanks for your response. What I meant was that validation should not compare the object that is being updated against its own existing copy. For example, I am editting an existing object: [:aspect => "Aspect-A", :user_id => 5, :third_field => "morning"]. Now, the object is unique in the database according to validates_uniqueness_of :aspect, :scope => :user_id That''s all good. However, when I update the object with the following statements: self.third_field = "night" save! Rails returns an error: ActiveRecord::RecordInvalid: Validation failed: Aspect has already been taken Why? I am just trying to update an existing object, not create a new one that would violate the uniqueness validation. Thanks. -- Posted via http://www.ruby-forum.com/.
2009/7/4 Learn by Doing <rails-mailing-list-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org>:> > Hi Nicholas, > > Thanks for your response. What I meant was that validation should not > compare the object that is being updated against its own existing copy. > For example, I am editting an existing object: > > [:aspect => "Aspect-A", :user_id => 5, :third_field => "morning"]. > > Now, the object is unique in the database according to > > validates_uniqueness_of :aspect, :scope => :user_id > > That''s all good. However, when I update the object with the following > statements: > > self.third_field = "night" > save! > > Rails returns an error: > > ActiveRecord::RecordInvalid: Validation failed: Aspect has > already been taken > > Why? I am just trying to update an existing object, not create a new > one that would violate the uniqueness validation.What code are you using for creating and modifying the object before saving it? Colin
Hi Colin, Thanks for asking that question. I had preloaded the database so I didn''t have to create a new record. So now I just tried doing that and it wouldn''t let me create a new record although the :aspect value I used does not exist at all in the database. Console output is below:>> stat0 = Stat.new(:user => user0, :aspect => "aspect0")=> #<Stat id: nil, user_id: 1000, aspect: "aspect0", . . .>>> stat0.save!ActiveRecord::RecordInvalid: Validation failed: Aspect has already been taken from /opt/local/lib/ruby/gems/1.8/gems/activerecord-2.3.2/lib/active_record/validations.rb:1021:in `save_without_dirty!'' from /opt/local/lib/ruby/gems/1.8/gems/activerecord-2.3.2/lib/active_record/dirty.rb:87:in `save_without_transactions!'' from /opt/local/lib/ruby/gems/1.8/gems/activerecord-2.3.2/lib/active_record/transactions.rb:200:in `save!'' from /opt/local/lib/ruby/gems/1.8/gems/activerecord-2.3.2/lib/active_record/connection_adapters/abstract/database_statements.rb:136:in `transaction'' from /opt/local/lib/ruby/gems/1.8/gems/activerecord-2.3.2/lib/active_record/transactions.rb:182:in `transaction'' from /opt/local/lib/ruby/gems/1.8/gems/activerecord-2.3.2/lib/active_record/transactions.rb:200:in `save!'' from /opt/local/lib/ruby/gems/1.8/gems/activerecord-2.3.2/lib/active_record/transactions.rb:208:in `rollback_active_record_state!'' from /opt/local/lib/ruby/gems/1.8/gems/activerecord-2.3.2/lib/active_record/transactions.rb:200:in `save!'' from (irb):70 "aspect0" is something I completely made up and does not exist in the database. :user_id 1000 does exist in different rows with different values of :aspect however. -- Posted via http://www.ruby-forum.com/.
On Sat, Jul 4, 2009 at 2:57 AM, Learn by Doing < rails-mailing-list-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> wrote:> > I have this in a model > > validates_uniqueness_of :aspect, :scope => :user_id > > In an instance method of the same model I have "save!" but I don''t touch > the :aspect attribute in that instance method at all. > > Whenever that save! command is run however I get this error: > > ActiveRecord::RecordInvalid: Validation failed: Aspect has > already been taken > > I don''t understand. The validation should not skip the instance from > which the method is called. Please help. Thanks. > -- > Posted via http://www.ruby-forum.com/. >What version of Rails are you using? Did you try this in Edge Rails? -Conrad> > > >--~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---
Hi Conrad, I am using Rails 2.3.2 and Ruby 1.8.7, the latest stable combination recommended by rubyonrails.org. I am continuing to troubleshoot this. I have deleted all the sample data that I preloaded so that my database is empty. Now, the opposite is happening, it is letting me create records in violation of the uniqueness validation:>> stat0 = Stat.new(:user_id => 1000, :aspect => "aspect0")=> #<Stat id: nil, user_id: 1000, aspect: "aspect0">>> stat0.save!=> true>> stat0 = Stat.new(:user_id => 1000, :aspect => "aspect0")=> #<Stat id: nil, user_id: 1000, aspect: "aspect0">>> stat0.save!=> true I check the database and yes it contains both of the above identical records. Only their :Stat_ids are different. Something wrong with my uniqueness validation? validates_uniqueness_of :aspect, :scope => :user_id Thanks. -- Posted via http://www.ruby-forum.com/.
2009/7/4 Learn by Doing <rails-mailing-list-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org>:> > Hi Conrad, > > I am using Rails 2.3.2 and Ruby 1.8.7, the latest stable combination > recommended by rubyonrails.org. > > I am continuing to troubleshoot this. I have deleted all the sample > data that I preloaded so that my database is empty. Now, the opposite > is happening, it is letting me create records in violation of the > uniqueness validation: > >>> stat0 = Stat.new(:user_id => 1000, :aspect => "aspect0") > => #<Stat id: nil, user_id: 1000, aspect: "aspect0"> >>> stat0.save! > => true >>> stat0 = Stat.new(:user_id => 1000, :aspect => "aspect0") > => #<Stat id: nil, user_id: 1000, aspect: "aspect0"> >>> stat0.save! > => true > > I check the database and yes it contains both of the above identical > records. Only their :Stat_ids are different. Something wrong with my > uniqueness validation? > > validates_uniqueness_of :aspect, :scope => :user_id >Can you post the model code and the db structure for this table please? Colin
Colin: Below are the relevant code. Thanks for your help. class CreateStats < ActiveRecord::Migration def self.up create_table :stats do |t| t.integer :user_id, :null => false t.string :aspect, :null => false, :default => "default aspect" t.timestamps end end def self.down drop_table :stats end end class Stat < ActiveRecord::Base belongs_to :user validates_presence_of :user_id validates_associated :user validates_uniqueness_of :aspect, :scope => :user_id attr_readonly :user_id, :aspect end -- Posted via http://www.ruby-forum.com/.
I haven''t been able to reproduce the issue that you have been having (on 2.3.2). I created a test suite for your model. Can you run that to see if you get the same problem. http://gist.github.com/141740 Requires mocha, update references to fixtures and fields as required. It''s based on the migration and model you provided. HTH, Nicholas On Jul 5, 11:59 pm, Learn by Doing <rails-mailing-l...-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> wrote:> Colin: > > Below are the relevant code. Thanks for your help. > > class CreateStats < ActiveRecord::Migration > > def self.up > create_table :stats do |t| > > t.integer :user_id, :null => false > t.string :aspect, :null => false, :default => "default > aspect" > > t.timestamps > end > end > > def self.down > drop_table :stats > end > end > > class Stat < ActiveRecord::Base > > belongs_to :user > validates_presence_of :user_id > validates_associated :user > > validates_uniqueness_of :aspect, :scope => :user_id > > attr_readonly :user_id, :aspect > > end > > -- > Posted viahttp://www.ruby-forum.com/.
Nicholas, Thank you very much for working on this. I ran the test suit but got errors. I modified the test suite: https://gist.github.com/4c009e230862d3a2e58a , using the users.yml: https://gist.github.com/1c282b5b006326cca497 Note that I changed the attribute name "aspect" to "score_aspect" Below are the errors. Thank you for your help. ruby test/unit/stat_test2.rb Loaded suite test/unit/stat_test2 Started E...EEEE Finished in 1.227252 seconds. 1) Error: test_should_add_error_on_score_aspect_when_validating_with_the_same_score_aspect (StatTest): ActiveRecord::RecordInvalid: Validation failed: Score aspect has already been taken test/unit/stat_test2.rb:33:in `test_should_add_error_on_score_aspect_when_validating_with_the_same_score_aspect'' 2) Error: test_should_not_add_error_on_score_aspect_when_validating_an_updated_stat (StatTest): ActiveRecord::RecordInvalid: Validation failed: Score aspect has already been taken test/unit/stat_test2.rb:41:in `test_should_not_add_error_on_score_aspect_when_validating_an_updated_stat'' 3) Error: test_should_not_add_error_on_score_aspect_when_validating_with_a_different_score_aspect (StatTest): ActiveRecord::RecordInvalid: Validation failed: Score aspect has already been taken test/unit/stat_test2.rb:25:in `test_should_not_add_error_on_score_aspect_when_validating_with_a_different_score_aspect'' 4) Error: test_should_score_aspect_be_read_only(StatTest): ActiveRecord::RecordInvalid: Validation failed: Score aspect has already been taken test/unit/stat_test2.rb:49:in `test_should_score_aspect_be_read_only'' 5) Error: test_should_user_be_read_only(StatTest): ActiveRecord::RecordInvalid: Validation failed: Score aspect has already been taken test/unit/stat_test2.rb:57:in `test_should_user_be_read_only'' 8 tests, 3 assertions, 0 failures, 5 errors On Jul 6, 3:53 pm, Nicholas Henry <nicholas.he...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> I haven''t been able to reproduce the issue that you have been having > (on 2.3.2). I created a test suite for your model. Can you run that to > see if you get the same problem. > > http://gist.github.com/141740 > > Requires mocha, update references to fixtures and fields as required. > It''s based on the migration and model you provided. > > HTH, > Nicholas > > On Jul 5, 11:59 pm, Learn by Doing <rails-mailing-l...-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> > wrote: > > > Colin: > > > Below are the relevant code. Thanks for your help. > > > class CreateStats < ActiveRecord::Migration > > > def self.up > > create_table :stats do |t| > > > t.integer :user_id, :null => false > > t.string :aspect, :null => false, :default => "default > > aspect" > > > t.timestamps > > end > > end > > > def self.down > > drop_table :stats > > end > > end > > > class Stat < ActiveRecord::Base > > > belongs_to :user > > validates_presence_of :user_id > > validates_associated :user > > > validates_uniqueness_of :aspect, :scope => :user_id > > > attr_readonly :user_id, :aspect > > > end > > > -- > > Posted viahttp://www.ruby-forum.com/. > >
Well you have me stumped, I ran your test suite against mine (after modifying the data structure) and it works. I''m assuming there is something in the mix that I''m not aware of. I''m not sure if it''s much help, but you can download my test app to see if that runs for you. http://files.me.com/nicholas.henry/0v2drf Cheers, Nicholas On Jul 17, 5:59 pm, Learn By Doing <ease...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> Nicholas, > > Thank you very much for working on this. > > I ran the test suit but got errors. I modified the test suite:https://gist.github.com/4c009e230862d3a2e58a, using the users.yml:https://gist.github.com/1c282b5b006326cca497 > > Note that I changed the attribute name "aspect" to "score_aspect" > > Below are the errors. Thank you for your help. > > ruby test/unit/stat_test2.rb > Loaded suite test/unit/stat_test2 > Started > E...EEEE > Finished in 1.227252 seconds. > > 1) Error: > test_should_add_error_on_score_aspect_when_validating_with_the_same_score_a spect > (StatTest): > ActiveRecord::RecordInvalid: Validation failed: Score aspect has > already been taken > test/unit/stat_test2.rb:33:in > `test_should_add_error_on_score_aspect_when_validating_with_the_same_score_ aspect'' > > 2) Error: > test_should_not_add_error_on_score_aspect_when_validating_an_updated_stat > (StatTest): > ActiveRecord::RecordInvalid: Validation failed: Score aspect has > already been taken > test/unit/stat_test2.rb:41:in > `test_should_not_add_error_on_score_aspect_when_validating_an_updated_stat'' > > 3) Error: > test_should_not_add_error_on_score_aspect_when_validating_with_a_different_ score_aspect > (StatTest): > ActiveRecord::RecordInvalid: Validation failed: Score aspect has > already been taken > test/unit/stat_test2.rb:25:in > `test_should_not_add_error_on_score_aspect_when_validating_with_a_different _score_aspect'' > > 4) Error: > test_should_score_aspect_be_read_only(StatTest): > ActiveRecord::RecordInvalid: Validation failed: Score aspect has > already been taken > test/unit/stat_test2.rb:49:in > `test_should_score_aspect_be_read_only'' > > 5) Error: > test_should_user_be_read_only(StatTest): > ActiveRecord::RecordInvalid: Validation failed: Score aspect has > already been taken > test/unit/stat_test2.rb:57:in `test_should_user_be_read_only'' > > 8 tests, 3 assertions, 0 failures, 5 errors > > On Jul 6, 3:53 pm, Nicholas Henry <nicholas.he...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > > > > > I haven''t been able to reproduce the issue that you have been having > > (on 2.3.2). I created a test suite for your model. Can you run that to > > see if you get the same problem. > > >http://gist.github.com/141740 > > > Requires mocha, update references to fixtures and fields as required. > > It''s based on the migration and model you provided. > > > HTH, > > Nicholas > > > On Jul 5, 11:59 pm, Learn by Doing <rails-mailing-l...-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> > > wrote: > > > > Colin: > > > > Below are the relevant code. Thanks for your help. > > > > class CreateStats < ActiveRecord::Migration > > > > def self.up > > > create_table :stats do |t| > > > > t.integer :user_id, :null => false > > > t.string :aspect, :null => false, :default => "default > > > aspect" > > > > t.timestamps > > > end > > > end > > > > def self.down > > > drop_table :stats > > > end > > > end > > > > class Stat < ActiveRecord::Base > > > > belongs_to :user > > > validates_presence_of :user_id > > > validates_associated :user > > > > validates_uniqueness_of :aspect, :scope => :user_id > > > > attr_readonly :user_id, :aspect > > > > end > > > > -- > > > Posted viahttp://www.ruby-forum.com/.