Lighthouse has a new layout. Prefer the old one? Return to the old layout, and switch back any time from the link at the top of each page.

This project is archived and is in readonly mode.

HABTM relation & update_attributes

#5855

Hi,

I have the following models:

class User < ActiveRecord::Base
  has_and_belongs_to_many :roles
end
class Role < ActiveRecord::Base
  has_and_belongs_to_many :users
end

Unless I'm wrong, there seems to be something broken when trying to update the role_ids of a user through update_attributes:

Without calling update_attributes, it works:

ruby-1.9.2-p0 > u = User.find(1)
 => #<User id: 1, email: "philippe.lang@attiksystem.ch"...
ruby-1.9.2-p0 > u.role_ids
 => [1] 
ruby-1.9.2-p0 > u.role_ids = [4, 5]
 => [4, 5] 
ruby-1.9.2-p0 > u.role_ids
 => [4, 5]

But this doesn't:

ruby-1.9.2-p0 >   u = User.find(1)
 => #<User id: 1, email: "philippe.lang@attiksystem.ch"...
ruby-1.9.2-p0 > u.role_ids
 => [1] 
ruby-1.9.2-p0 > u.update_attributes({:role_ids => [4,5]})
 => true 
ruby-1.9.2-p0 > u.role_ids
 => [1] 
ruby-1.9.2-p0 > u.save
 => true 
ruby-1.9.2-p0 > u.role_ids
 => [1]

I made sure I was calling update_attributes correctly, and it seems to be the case:

ruby-1.9.2-p0 > u.update_attributes({:email => "changed@attiksystem.ch"})
 => true 
ruby-1.9.2-p0 > u
 => #<User id: 1, email: "changed@attiksystem.ch"...

Am I doing anything wrong? These tests were made with Rails 3.01.

Best regards,

Philippe

Reported by Philippe Lang · October 22nd, 2010 @ 04:00 PM

State: invalid
Milestone: none
Assigned to: nobody
Importance: Low

Activity

  1. Cesario
    Cesario

    Hi Phil,
    I can't reproduce this behavior locally. Do you have specific validation method somewhere that could be interesting to look at?

    October 23rd, 2010 @ 01:50 PM

  2. Cesario
    Cesario
    • Tag set to activerecord 3.0, 3.0

    October 23rd, 2010 @ 01:51 PM

  3. Philippe Lang
    Philippe Lang

    Hi Cesario,

    The only thing I did not mention is that the users table has been generated by devise. The model looks like this:

    class User < ActiveRecord::Base
      has_and_belongs_to_many :roles
      has_many :mailings
      
      # Include default devise modules. Others available are:
      # :token_authenticatable, :confirmable, :lockable and :timeoutable
      devise :database_authenticatable, :registerable,
             :recoverable, :rememberable, :trackable, :validatable
    
      # Setup accessible (or protected) attributes for your model
      attr_accessible :email, :password, :password_confirmation, :remember_me
      
      def is?(role)
        self.roles.where(:name => role).exists?
      end
    end
    

    I'll try disabling a few options, and maybe it will start working again...

    Philippe

    October 23rd, 2010 @ 04:41 PM

  4. Philippe Lang
    Philippe Lang

    Sorry, this was my mistake. I had to add :role_ids in the list of accessible attributes and now it works great.

    attr_accessible :email, :password, :password_confirmation, :remember_me, :role_ids
    

    Is there a way of getting an error in such a case? When the :role_ids attribute is not accessible, update_attributes fails without saying anything...

    October 23rd, 2010 @ 04:51 PM

  5. Aditya Sanghi
    Aditya Sanghi
    • State changed from new to invalid
    • Importance changed from to Low

    Have a look in the logs, mass assigning protected attributes throws a warning message in development mode i believe.

    Marking ticket as invalid.

    October 23rd, 2010 @ 05:32 PM