This project is archived and is in readonly mode.

#5855 ✓invalid
Philippe Lang

HABTM relation & update_attributes

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

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

Comments and changes to this ticket

  • Cesario

    Cesario October 23rd, 2010 @ 01:50 PM

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

  • Cesario

    Cesario October 23rd, 2010 @ 01:51 PM

    • Tag set to activerecord 3.0, 3.0
  • Philippe Lang

    Philippe Lang October 23rd, 2010 @ 04:41 PM

    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

  • Philippe Lang

    Philippe Lang October 23rd, 2010 @ 04:51 PM

    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...

  • Aditya Sanghi

    Aditya Sanghi October 23rd, 2010 @ 05:32 PM

    • 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.

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