最近發(fā)現(xiàn)又有小伙伴被 ClassName.current_user 給坑了,導致數(shù)據(jù)保存的不是預期的用戶id。所以覺得有必要詳細梳理一下這塊。
| 格式 | 名稱 | 是否需要初始化 | 作用范圍 | 例子 |
|---|---|---|---|---|
| $開頭 | 全局變量 | 不需要,初始化前值為nil | 全局 | $user |
| @@開頭 | 類變量 | 需要,直接使用報錯 | 類內(nèi)直接使用,外部通過類名調(diào)用 | @@user |
| @開頭 | 實例變量 | 不需要,初始化前值為nil | 實例化的類內(nèi)部 | @user |
| 大寫字母 | 常量 | 只能被賦值一次,多次賦值會警告不會報錯 | 類內(nèi)部外呼均可用,外部通過類名訪問 | 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
在這里我們緩存用的是線程實例的形式保存的,但是一般我們會使用全局變量和類變量
這兩種方式的區(qū)別如下:
全局變量或類變量
全局變量(類變量) 是在整個進程有效線程變量
Thread.current[:a]用法,我稱之為線程變量
在當前線程有效,同一進程的其他線程不會獲取到
這兩種方式如果在多進程模式的unicorn下是一樣的
但是在多線程模式的puma下會有一些區(qū)別,第二種方式會占用多一些內(nèi)存
ok,經(jīng)過上面的分析我們知道了兩種緩存方式都會將緩存信息保存在進程(或線程)中,直到程序終止或者我們改變它,所以這就導致了我們使用出現(xiàn)問題。
因為在項目中緩存被我們用來在controller與model中傳遞數(shù)據(jù),所以我們需要在每次訪問開始前設置上面緩存的值,否則我們就會調(diào)用到上一次訪問設置的值。