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 => "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
=> #<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">
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: "dummy@email.com", 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: "dummy@email.com", 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._%+-]+@[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 Update、それが機能することを示すために:
sqlite> 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> 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|dummy@email.com|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" = '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 `<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")