2012-04-05 107 views
2

我没有一个问题,我似乎无法更新或修改栏3中的数据库列。我从来没有见过像这样的事情,因此,我确信这是我忽略的小事。请帮忙!Rails 3:数据库列不会通过活动记录更新

IRB输出:

ruby-1.9.2-p318 :002 > User.all 
     User Load (0.1ms) SELECT "users".* FROM "users" 
    => [] 
    ruby-1.9.2-p318 :003 > User.create(:login => "dummy", :password => "foobar", :password_ 
    confirmation => "foobar", :role => "user", :email => "[email protected]") 
     (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" = '[email protected]' 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", "[email protected]"], ["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 
    => #<User id: 3, login: "dummy", role: nil, hashed_password: "6416111c47fa52ddfbde9e539 
    ee6e369807bdeab", email: "[email protected]", salt: "1LTzevgRHt", created_at: "2012-04-05 
    02:21:00", updated_at: "2012-04-05 02:21:00"> 
    ruby-1.9.2-p318 :004 > u = User.first 
     User Load (0.2ms) SELECT "users".* FROM "users" LIMIT 1 
    => #<User id: 3, login: "dummy", role: nil, hashed_password: "6416111c47fa52ddfbde9e539 
    ee6e369807bdeab", email: "[email protected]", salt: "1LTzevgRHt", created_at: "2012-04-05 
    02:21:00", updated_at: "2012-04-05 02:21:00"> 
    ruby-1.9.2-p318 :005 > u.role 
    => nil 
    ruby-1.9.2-p318 :006 > u.role = "foo" 
    => "foo" 
    ruby-1.9.2-p318 :007 > u.role 
    => "foo" 
    ruby-1.9.2-p318 :008 > u 
    => #<User id: 3, login: "dummy", role: nil, hashed_password: "6416111c47fa52ddfbde9e539 
    ee6e369807bdeab", email: "[email protected]", salt: "1LTzevgRHt", created_at: "2012-04-05 
    02:21:00", updated_at: "2012-04-05 02:21:00"> 

迁移:

class CreateUsers < 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 

架构:

ActiveRecord::Schema.define(:version => 20120318205424) do 

     create_table "users", :force => true do |t| 
     t.string "login" 
     t.string "role" 
     t.string "hashed_password" 
     t.string "email" 
     t.string "salt" 
     t.datetime "created_at",  :null => false 
     t.datetime "updated_at",  :null => false 
     end 

    end 

型号:

require 'digest/sha1' 
    class User < ActiveRecord::Base 
     validates_length_of :login, :within => 3..40 
     validates_length_of :password, :within => 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 => /^[A-Z0-9._%+-][email protected][A-Z0-9.-]+\.[A-Z]{2,4}$/i, :message => "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 << 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=>["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 

SQLite的更新,以显示它的工作原理:

sqlite> select * from users; 
    3|dummy||6416111c47fa52ddfbde9e539ee6e369807bdeab|[email protected]|1LTzevgRHt|2012-04-05 02:21:00.752890|2012-04-05 02:21:00.752890 
    sqlite> select role from users; 

    sqlite> select role from users where login = "dummy"; 

    sqlite> update users set role = "user" where login = "dummy"; 
    sqlite> select role from users where login = "dummy"; 
    user 
    sqlite> select * from users; 
    3|dummy|user|6416111c47fa52ddfbde9e539ee6e369807bdeab|[email protected]|1LTzevgRHt|2012-04-05 02:21:00.752890|2012-04-05 02:21:00.752890 

我一直是这样瞎搞了一阵子...感谢您的帮助,您可以给。

编辑要求:

ruby-1.9.2-p318 :011 > User.last.update_attributes!(:role => "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" = '[email protected]' 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 `<top (required)>' 
      from script/rails:6:in `require' 
      from script/rails:6:in `<main>'ruby-1.9.2-p318 :012 > User.last.update_attributes!(:role => "foo") 
+0

可以粘贴的'User.last.update_attributes输出中删除:role!(:角色=> “富”)' – shime 2012-04-05 02:41:59

+0

我我已经添加了它。注意我已经尝试确保密码和password_confirmation符合验证要求。我很确定这不是问题。 – jmervine 2012-04-05 03:34:34

回答

4

从该行attr_accessor :password, :password_confirmation, :role

+0

好的,那有效......如果你不介意,为什么? – jmervine 2012-04-05 03:36:15

+3

向模式中添加':role'时,ActiveRecord知道当你说'user.role'时,它应该从'@ attributes'散列中读取,这个散列在用户从数据库中读取时被填充,当你分配给'user.role',它应该写入'@ attributes'哈希。实质上,ActiveRecord正在为您创建#role和#role =方法来执行此操作。所以有两件事:1)通过说'attr_accessor:role',你可以覆盖这些方法。 2)当你说'user.inspect'时,'@ attributes'哈希值被读取,所以你的改变看起来不会生效。 – 2012-04-05 04:39:42

+1

当您将'role'定义为访问者时,它会覆盖AR的读写器方法 – MikDiet 2012-04-05 04:40:51

相关问题