controller與model 傳遞數據不要使用緩存

最近發現又有小伙伴被 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中傳遞數據,所以我們需要在每次訪問開始前設置上面緩存的值,否則我們就會調用到上一次訪問設置的值。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。