新手问题 求教一个 ruby/rails 的 self 的问题

eva · 2013年03月06日 · 最后由 eva 回复于 2013年03月14日 · 2981 次阅读

在 railscasts-china 里第二篇讲#002 User Authentication 的时候(http://railscasts-china.com/episodes/user-authentication?view=comments),user model 的代码如下: class User < ActiveRecord::Base validates :login, :presence => true

def password @password end

def password=(pass) return unless pass @password = pass generate_password(pass) end

# 此处用动词形式 (authenticate) 更加合适,特此说明一下。感谢 Chen Kai 同学的提醒. def self.authentication(login, password) user = User.find_by_login(login) if user && Digest::SHA256.hexdigest(password + user.salt) == user.hashed_password return user end false end

private def generate_password(pass) salt = Array.new(10){rand(1024).to_s(36)}.join self.salt, self.hashed_password = salt, Digest::SHA256.hexdigest(pass + salt) end end

想问下在 generate_password 方法里,self.salt = salt,这里一定要用 self.salt 才行吗?为什么不能直接用@salt = salt?

可以@吧

那为什么我改为@后,在 rails c 里,看到 salt 是 nil,而没有被真正的赋值呢? 如下: ➜ authentication rails c Loading development environment (Rails 3.2.11) 1.9.3-p374 :001 > User.count (0.1ms) SELECT COUNT() FROM "users" => 0 1.9.3-p374 :002 > User.create(:login => "eva", :password => "foobar") (0.1ms) begin transaction SQL (4.5ms) INSERT INTO "users" ("created_at", "hashed_password", "login", "salt", "updated_at") VALUES (?, ?, ?, ?, ?) ["created_at", Wed, 06 Mar 2013 03:36:19 UTC +00:00], ["hashed_password", nil], ["login", "eva"], ["salt", nil], ["updated_at", Wed, 06 Mar 2013 03:36:19 UTC +00:00] commit transaction => # 1.9.3-p374 :003 > User.first User Load (0.3ms) SELECT "users". FROM "users" LIMIT 1 => # 1.9.3-p374 :004 >

你先把代码整理下吧,看帮助。

#3 楼 @chenge 代码有什么问题需要整理?

m 键,帮助有说明

#4 楼 @eva

在 railscasts-china 里第二篇讲#002 User Authentication 的时候(http://railscasts-china.com/episodes/user-authentication?view=comments),user model 的代码如下:

class User < ActiveRecord::Base
  validates :login, :presence => true

  def password
    @password
  end

def password=(pass)
  return unless pass
  @password = pass
  generate_password(pass)
end

此处用动词形式 (authenticate) 更加合适,特此说明一下。感谢 Chen Kai 同学的提醒。

def self.authentication(login, password)
  user = User.find_by_login(login)
  if user && Digest::SHA256.hexdigest(password + user.salt) == user.hashed_password
    return user
  end
  false
end

private
def generate_password(pass)
  salt = Array.new(10){rand(1024).to_s(36)}.join
  self.salt, self.hashed_password =
  salt, Digest::SHA256.hexdigest(pass + salt)
end

想问下在generate_password方法里,self.salt = salt,这里一定要用self.salt才行吗?为什么不能直接用@salt = salt

password=,是这里才执行的。你试试看

#6 楼 @zgm 谢谢

#7 楼 @chenge 在 password=()下去调用了 generate_password 方法,不是一样么

#8 楼 @eva u=User.new u.password = 'abc' p u.inspect

试试看

参看:http://forums.pragprog.com/forums/22/topics/217

大概意思是:@password 是实例变量,对应的数据库表并没有这个字段;而 self.salt 对应的是 rails 帮你生成的方法,与数据库表字段同名。

#10 楼 @codeframe 谢谢,后面说的没道理,但连接里解释清楚了: I suppose that self.salt = ... is used so that the method generated by rails is called, rather than assigning to the instance variable, which would be making an assumption about the rails implementation. In fact, if you inspect the user (with user.inspect) you will see that rails doesn’t even create an instance variable called @salt. Instead, all of the attributes generated by inspecting the database schema are put in a hash called attributes: “123”, “name”=>”benjamin”, “hashed_password”=>”a335e63a110911315788dbe5b1d44815bdd528ae”, “id”=>2}

The accessor method ‘salt’ must retrieve the value from the @attributes hash.

需要 登录 后方可回复, 如果你还没有账号请 注册新账号