save! not allowed after validates_uniqueness

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

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.

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

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

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

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