基于rails的schedule网站开发(13):用send 方法改写authenticated?(...)

abstract:
元编程(metaprogramming)——send方法

title 1
title 2
title 3

send方法的作用是在指定的对象上调用指定的方法
例如,在下面的控制台会话中,我们在一个 Ruby 原生对象上调用 send 方法,获取数组的长度:

$ rails console
>> a = [1, 2, 3]
>> a.length
=> 3
>> a.send(:length)
=> 3
>> a.send('length')
=> 3

可以看出,把 :length 符号或者 ‘length’ 字符串传给 send 方法的作用和在对象上直接调用 length 方法的作用一样。再看一个例子,获取数据库中第一个用户的 activation_digest 属性:

>> user = User.first
>> user.activation_digest
=> "$2a$10$4e6TFzEJAVNyjLv8Q5u22ensMt28qEkx0roaZvtRcp6UZKRM6N9Ae"
>> user.send(:activation_digest)
=> "$2a$10$4e6TFzEJAVNyjLv8Q5u22ensMt28qEkx0roaZvtRcp6UZKRM6N9Ae"
>> user.send('activation_digest')
=> "$2a$10$4e6TFzEJAVNyjLv8Q5u22ensMt28qEkx0roaZvtRcp6UZKRM6N9Ae"
>> attribute = :activation
>> user.send("#{attribute}_digest")
=> "$2a$10$4e6TFzEJAVNyjLv8Q5u22ensMt28qEkx0roaZvtRcp6UZKRM6N9Ae"

注意最后一种调用方式,我们定义了一个 attribute 变量,其值为符号 :activation,然后使用字符串插值构建传给 send 方法的参数。attribute 变量的值使用字符串 ‘activation’ 也行,不过符号更便利。不管使用什么,插值后,”#{attribute}_digest” 的结果都是 “activation_digest”。
基于上述对 send 方法的介绍,我们可以把 authenticated? 方法改写成:

def authenticated?(remember_token)
  digest = self.send('remember_digest')
  return false if digest.nil?
  BCrypt::Password.new(digest).is_password?(remember_token)
end

以此为模板,我们可以为这个方法增加一个参数,代表摘要的名字,然后再使用字符串插值,扩大这个方法的用途:

def authenticated?(attribute, token)
  digest = self.send("#{attribute}_digest")
  return false if digest.nil?
  BCrypt::Password.new(digest).is_password?(token)
end

(我们把第二个参数的名字改成了 token,以此强调这个方法的用途更广。)因为这个方法在用户模型内,所以可以省略 self,得到更符合习惯写法的版本:

def authenticated?(attribute, token)
  digest = send("#{attribute}_digest")
  return false if digest.nil?
  BCrypt::Password.new(digest).is_password?(token)
end

现在我们可以像下面这样调用 authenticated? 方法实现以前的效果:
user.authenticated?(:remember, remember_token)

在书中的这种改变,是为了让uthenticated?(…)方法可以用于验证登陆用户是否是cookie中保持的用户,又可以用于验证用户是否是邮箱验证过的用户。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值