This project is archived and is in readonly mode.

#6566 new
Joey

accepts_nested_attributes_for not updating correctly with validates_uniqueness_of

Reported by Joey | March 12th, 2011 @ 06:25 AM

If I create a Team and add two users to it through UsersTeam, one with a position of "leader" and another with a position of "follower", I receive a uniqueness validation error when I swap the positions on a Team form with UsersTeams nested.

class User 
has_many :users_teams
end

class Team
has_many :users_teams
accepts_nested_attributes_for :users_teams
end

class UsersTeam
belongs_to :user
belongs_to :team

validates_presence_of :position
validates_uniqueness_of :position, :scope => :team_id #Two users with the same position cannot be on the same team
end

Comments and changes to this ticket

  • Dan Pickett

    Dan Pickett March 12th, 2011 @ 04:27 PM

    Joey,

    Can you provide a failing test that verifies this errant behavior?

  • Joey

    Joey March 19th, 2011 @ 10:37 AM

    I'm not to good with creating test cases. I pushed an app to github with the following instructions to reproduce the bug.

    https://github.com/joeytheman/Rails3-Bug6566

    How to reproduce Rails Lighthouse Bug [#6566](/projects/8994/tickets/6566 "Ticket #6566")
    
    1. Download source from git://github.com/joeytheman/Rails3-Bug6566.git .
    
    2. Run "bundle install".
    
    3. Run "rake db:schema:load".
    
    4. Navigate to "/users" and create 2 users.
    
    5. Navigate to "/team" and create a new team with 2 teammates with the following parameters
        -Teammate 1
        -- User => 1
        -- Team => nil
        -- Position => "C"
    
        -Teammate 2
        -- User => 2
        -- Team => nil
        -- Position => "A"
    
    6. Navigate to "/team/1/edit".
    
    7. Set the position of player 1 to "A" and the position of player 2 to "C".
    
    8. Attempt to save.
    
  • Pablo

    Pablo March 24th, 2011 @ 09:00 PM

    Hello, I've downloaded to mac the app in Github, follow steps but didn't reproduce the bug, it changed correctly from one value to the other.
    I'll try later to do the same on windows, I think you are using Windows, don't you?
    Regards,

  • Joey

    Joey March 24th, 2011 @ 09:18 PM

    I checked my repo and realized I had the validation commented out from testing in users_team.rb. If you pull the repo again you can verify the bug. And I'm using windows 7 x64, Ruby 1.9.2p180, and rails 3.0.5. Sorry for the inconvenience.

  • Pablo

    Pablo March 25th, 2011 @ 11:32 PM

    Hi. Now I can reproduce it. It even fails when doing in a transaction, ie:

    https://gist.github.com/887397

    ActiveRecord::RecordInvalid: Validation failed: Position has already been taken

    The problem is that the SQLs run before updating the database so you get:

    UsersTeam Load (0.2ms) SELECT "users_teams"."id" FROM "users_teams" WHERE "users_teams"."team_id" = 1 AND ("users_teams"."position" = 'p2') AND ("users_teams".id <> 1) LIMIT 1

    AREL (0.8ms) UPDATE "users_teams" SET "position" = 'p2', "updated_at" = '2011-03-25 19:10:46.892606' WHERE "users_teams"."id" = 1

  • Pablo

    Pablo March 28th, 2011 @ 12:57 AM

    Ok, here is a test that fails:

    May add it to test/cases/validations/uniqueness_validation_test.rb

    def test_validate_uniqueness_when_swapping_values_within_transaction

    Event.new( title:'E1').save!
    Event.new( title:'E2').save!
    ActiveRecord::Base.transaction do
      e1 = Event.find(1)
      e2 = Event.find(2)
      e1.title = 'E2'
      e2.title = 'E1'
      e2.save
      e1.save
    end
    assert_equal Event.find(1).title, 'E2'
    assert_equal Event.find(2).title, 'E1'
    

    end

Create your profile

Help contribute to this project by taking a few moments to create your personal profile. Create your profile »

<h2 style="font-size: 14px">Tickets have moved to Github</h2>

The new ticket tracker is available at <a href="https://github.com/rails/rails/issues">https://github.com/rails/rails/issues</a>

People watching this ticket

Pages