最近发现又有小伙伴被 ClassName.current_user 给坑了,导致数据保存的不是预期的用户id。所以觉得有必要详细梳理一下这块。
格式 | 名称 | 是否需要初始化 | 作用范围 | 例子 |
---|---|---|---|---|
$开头 | 全局变量 | 不需要,初始化前值为nil | 全局 | $user |
@@开头 | 类变量 | 需要,直接使用报错 | 类内直接使用,外部通过类名调用 | @@user |
@开头 | 实例变量 | 不需要,初始化前值为nil | 实例化的类内部 | @user |
大写字母 | 常量 | 只能被赋值一次,多次赋值会警告不会报错 | 类内部外呼均可用,外部通过类名访问 | USER |
我们一般缓存的代码(ClassName.current_user)
module ClassName
class << self
def current_user_id
Thread.current[:user]
end
def current_user_id=(user)
Thread.current[:user] = user
end
end
end
在这里我们缓存用的是线程实例的形式保存的,但是一般我们会使用全局变量和类变量
这两种方式的区别如下:
全局变量或类变量
全局变量(类变量) 是在整个进程有效线程变量
Thread.current[:a]
用法,我称之为线程变量
在当前线程有效,同一进程的其他线程不会获取到
这两种方式如果在多进程模式的unicorn下是一样的
但是在多线程模式的puma下会有一些区别,第二种方式会占用多一些内存
ok,经过上面的分析我们知道了两种缓存方式都会将缓存信息保存在进程(或线程)中,直到程序终止或者我们改变它,所以这就导致了我们使用出现问题。
因为在项目中缓存被我们用来在controller与model中传递数据,所以我们需要在每次访问开始前设置上面缓存的值,否则我们就会调用到上一次访问设置的值。