title: Rails 3: Database column won't update through active record
body: <p>I haven't an issue where I can't seem to update or modify a database column in rails 3. I've never seen anything like this before and as such am sure it's something small that I'm overlooking. Please help!</p>
  
  <p>IRB Output:</p>
  
  <pre><code>    ruby-1.9.2-p318 :002 &gt; User.all
        User Load (0.1ms)  SELECT "users".* FROM "users" 
       =&gt; [] 
      ruby-1.9.2-p318 :003 &gt; User.create( :login =&gt; "dummy", :password =&gt; "foobar", :password_
      confirmation =&gt; "foobar", :role =&gt; "user", :email =&gt; "dummy@email.com" )
         (0.1ms)  begin transaction
        User Exists (0.1ms)  SELECT 1 FROM "users" WHERE "users"."login" = 'dummy' LIMIT 1
        User Exists (0.0ms)  SELECT 1 FROM "users" WHERE "users"."email" = 'dummy@email.com' L
      IMIT 1
        SQL (0.8ms)  INSERT INTO "users" ("created_at", "email", "hashed_password", "login", "
      role", "salt", "updated_at") VALUES (?, ?, ?, ?, ?, ?, ?)  [["created_at", Thu, 05 Apr 2
      012 02:21:00 UTC +00:00], ["email", "dummy@email.com"], ["hashed_password", "6416111c47f
      a52ddfbde9e539ee6e369807bdeab"], ["login", "dummy"], ["role", nil], ["salt", "1LTzevgRHt
      "], ["updated_at", Thu, 05 Apr 2012 02:21:00 UTC +00:00]]
         (61.5ms)  commit transaction
       =&gt; #&lt;User id: 3, login: "dummy", role: nil, hashed_password: "6416111c47fa52ddfbde9e539
      ee6e369807bdeab", email: "dummy@email.com", salt: "1LTzevgRHt", created_at: "2012-04-05 
      02:21:00", updated_at: "2012-04-05 02:21:00"&gt; 
      ruby-1.9.2-p318 :004 &gt; u = User.first
        User Load (0.2ms)  SELECT "users".* FROM "users" LIMIT 1
       =&gt; #&lt;User id: 3, login: "dummy", role: nil, hashed_password: "6416111c47fa52ddfbde9e539
      ee6e369807bdeab", email: "dummy@email.com", salt: "1LTzevgRHt", created_at: "2012-04-05 
      02:21:00", updated_at: "2012-04-05 02:21:00"&gt; 
      ruby-1.9.2-p318 :005 &gt; u.role 
       =&gt; nil 
      ruby-1.9.2-p318 :006 &gt; u.role = "foo"
       =&gt; "foo" 
      ruby-1.9.2-p318 :007 &gt; u.role
       =&gt; "foo" 
      ruby-1.9.2-p318 :008 &gt; u
       =&gt; #&lt;User id: 3, login: "dummy", role: nil, hashed_password: "6416111c47fa52ddfbde9e539
      ee6e369807bdeab", email: "dummy@email.com", salt: "1LTzevgRHt", created_at: "2012-04-05 
      02:21:00", updated_at: "2012-04-05 02:21:00"&gt; 
  </code></pre>
  
  <p>Migration:</p>
  
  <pre><code>    class CreateUsers &lt; ActiveRecord::Migration
        def change
          create_table :users do |t|
            t.column :login, :string
            t.column :role, :string
            t.column :hashed_password, :string
            t.column :email, :string
            t.column :salt, :string
            t.timestamps
          end
        end
      end
  </code></pre>
  
  <p>Schema:</p>
  
  <pre><code>    ActiveRecord::Schema.define(:version =&gt; 20120318205424) do
  
        create_table "users", :force =&gt; true do |t|
          t.string   "login"
          t.string   "role"
          t.string   "hashed_password"
          t.string   "email"
          t.string   "salt"
          t.datetime "created_at",      :null =&gt; false
          t.datetime "updated_at",      :null =&gt; false
        end
  
      end
  </code></pre>
  
  <p>Model:</p>
  
  <pre><code>    require 'digest/sha1'
      class User &lt; ActiveRecord::Base
        validates_length_of :login, :within =&gt; 3..40
        validates_length_of :password, :within =&gt; 4..40
        validates_presence_of :login, :email, :password, :password_confirmation, :salt
        validates_uniqueness_of :login, :email
        validates_confirmation_of :password
        validates_format_of :email, :with =&gt; /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i, :message =&gt; "Invalid email"  
  
        attr_accessor :password, :password_confirmation, :role
        attr_protected :id, :salt
  
        def self.random_string(len)
          chars = ("a".."z").to_a + ("A".."Z").to_a + ("0".."9").to_a
          newpass = ""
          1.upto(len) { |i| newpass &lt;&lt; chars[rand(chars.size-1)] }
          return newpass
        end
  
        def password=(pass)
          @password=pass
          self.salt = User.random_string(10) if !self.salt?
          self.hashed_password = User.encrypt(@password, self.salt)
        end
  
        def self.encrypt(pass, salt)
          Digest::SHA1.hexdigest("#{pass}#{salt}")
        end
  
        def self.authenticate(login, pass)
          u=find(:first, :conditions=&gt;["login = ?", login])
          return nil if u.nil?
          if User.encrypt(pass, u.salt)==u.hashed_password
            # edits wont save without this
            u.password=u.password_confirmation=pass
            return u
          end
          nil
        end
  
        def send_new_password
          new_pass = User.random_string(10)
          self.password = self.password_confirmation = new_pass
          self.save
          Notification.deliver_forgot_password(self.email, self.login, new_pass)
        end
  
        def admin?
          (self.role == "admin")
        end
  
      end
  </code></pre>
  
  <p>SQLite Update, to show it works:</p>
  
  <pre><code>    sqlite&gt; select * from users;
      3|dummy||6416111c47fa52ddfbde9e539ee6e369807bdeab|dummy@email.com|1LTzevgRHt|2012-04-05 02:21:00.752890|2012-04-05 02:21:00.752890
      sqlite&gt; select role from users;
  
      sqlite&gt; select role from users where login = "dummy";
  
      sqlite&gt; update users set role = "user" where login = "dummy";
      sqlite&gt; select role from users where login = "dummy";
      user
      sqlite&gt; select * from users;
      3|dummy|user|6416111c47fa52ddfbde9e539ee6e369807bdeab|dummy@email.com|1LTzevgRHt|2012-04-05 02:21:00.752890|2012-04-05 02:21:00.752890
  </code></pre>
  
  <p>I've been messing with this for a while... thanks for any help you can give.</p>
  
  <p>EDIT on request:</p>
  
  <pre><code>    ruby-1.9.2-p318 :011 &gt; User.last.update_attributes!(:role =&gt; "foo") 
        User Load (0.2ms)  SELECT "users".* FROM "users" ORDER BY "users"."id" DESC LIMIT 1
         (0.1ms)  begin transaction
        User Exists (0.1ms)  SELECT 1 FROM "users" WHERE ("users"."login" = 'dummy' AND "users"."id" != 3) LIMIT 1
        User Exists (0.1ms)  SELECT 1 FROM "users" WHERE ("users"."email" = 'dummy@email.com' AND "users"."id" != 3) LIMIT 1
         (0.1ms)  rollback transaction
      ActiveRecord::RecordInvalid: Validation failed: Password is too short (minimum is 4 characters), Password can't be blank, Password confirmation can't be blank
              from /home/jmervine/Development/personal/blog/vendor/bundle/ruby/1.9.1/gems/activerecord-3.2.2/lib/active_record/validations.rb:56:in `save!'
              from /home/jmervine/Development/personal/blog/vendor/bundle/ruby/1.9.1/gems/activerecord-3.2.2/lib/active_record/attribute_methods/dirty.rb:33:in `save!'
              from /home/jmervine/Development/personal/blog/vendor/bundle/ruby/1.9.1/gems/activerecord-3.2.2/lib/active_record/transactions.rb:246:in `block in save!'
              from /home/jmervine/Development/personal/blog/vendor/bundle/ruby/1.9.1/gems/activerecord-3.2.2/lib/active_record/transactions.rb:295:in `block in with_transaction_returning_status'
              from /home/jmervine/Development/personal/blog/vendor/bundle/ruby/1.9.1/gems/activerecord-3.2.2/lib/active_record/connection_adapters/abstract/database_statements.rb:192:in `transaction'
              from /home/jmervine/Development/personal/blog/vendor/bundle/ruby/1.9.1/gems/activerecord-3.2.2/lib/active_record/transactions.rb:208:in `transaction'
              from /home/jmervine/Development/personal/blog/vendor/bundle/ruby/1.9.1/gems/activerecord-3.2.2/lib/active_record/transactions.rb:293:in `with_transaction_returning_status'
              from /home/jmervine/Development/personal/blog/vendor/bundle/ruby/1.9.1/gems/activerecord-3.2.2/lib/active_record/transactions.rb:246:in `save!'
              from /home/jmervine/Development/personal/blog/vendor/bundle/ruby/1.9.1/gems/activerecord-3.2.2/lib/active_record/persistence.rb:224:in `block in update_attributes!'
              from /home/jmervine/Development/personal/blog/vendor/bundle/ruby/1.9.1/gems/activerecord-3.2.2/lib/active_record/transactions.rb:295:in `block in with_transaction_returning_status'
              from /home/jmervine/Development/personal/blog/vendor/bundle/ruby/1.9.1/gems/activerecord-3.2.2/lib/active_record/connection_adapters/abstract/database_statements.rb:192:in `transaction'
              from /home/jmervine/Development/personal/blog/vendor/bundle/ruby/1.9.1/gems/activerecord-3.2.2/lib/active_record/transactions.rb:208:in `transaction'
              from /home/jmervine/Development/personal/blog/vendor/bundle/ruby/1.9.1/gems/activerecord-3.2.2/lib/active_record/transactions.rb:293:in `with_transaction_returning_status'
              from /home/jmervine/Development/personal/blog/vendor/bundle/ruby/1.9.1/gems/activerecord-3.2.2/lib/active_record/persistence.rb:222:in `update_attributes!'
              from (irb):11
              from /home/jmervine/Development/personal/blog/vendor/bundle/ruby/1.9.1/gems/railties-3.2.2/lib/rails/commands/console.rb:47:in `start'
              from /home/jmervine/Development/personal/blog/vendor/bundle/ruby/1.9.1/gems/railties-3.2.2/lib/rails/commands/console.rb:8:in `start'
              from /home/jmervine/Development/personal/blog/vendor/bundle/ruby/1.9.1/gems/railties-3.2.2/lib/rails/commands.rb:41:in `&lt;top (required)&gt;'
              from script/rails:6:in `require'
              from script/rails:6:in `&lt;main&gt;'ruby-1.9.2-p318 :012 &gt; User.last.update_attributes!(:role =&gt; "foo") 
  </code></pre>