【问题标题】:List sessions for current user only in Rails仅在 Rails 中列出当前用户的会话
【发布时间】:2017-01-18 22:42:33
【问题描述】:

我正在使用activerecord-session_store gem 将会话存储在数据库中。

我在我的 SessionsController 中使用此方法列出会话:

def index
  @sessions = Session.all
end

但是,这会列出应用程序中的所有会话,而不仅仅是当前登录用户的会话。会话的数据库表具有以下列:id, session_id, data, created_at, updated_at,因此没有要过滤的 user_id 列。

我可以用Marshal.load(Base64.decode64(session.data))['user_id']访问会话数据中的user_id

如何使用这些数据来过滤列表?到目前为止,我能想到的只是在视图中做一个条件,将它与current_user.id进行比较

例如

<% @sessions.each do |session| %>
  <% if Marshal.load(Base64.decode64(session.data))['user_id'] == current_user.id %>
    <!-- LIST SESSION -->
  <% end %>
<% end %>

【问题讨论】:

    标签: ruby-on-rails ruby session


    【解决方案1】:

    如果你使用PostgreSQL作为后端,你可以简单地设置一个序列化to be :json

    ActiveRecord::SessionStore::Session.serializer = :json
    

    并针对 postgres 查询 json 字段。


    如果你使用MySQL,你可以实现你自己的会话类:

    ActionDispatch::Session::ActiveRecordStore.session_class = MySessionClass
    

    并实现pre_commit 挂钩,将user_id 明确保存在表的相应列中。之后只需查询此列。

    【讨论】:

    • 使用 Postgres,:json 将存储为字符串,即使您的列是 JSONB。要存储正确的类型,请使用ActiveRecord::SessionStore::Session.serializer = :null(将序列化推迟到 ActiveRecord 数据库适配器)。源代码中的更多细节:github.com/rails/activerecord-session_store/blob/…
    【解决方案2】:

    如果我没记错的话,你可以在控制器中使用相同的调用current_user;因此,如果您在该控制器/路由上设置before_filter,您可以使用相同的代码过滤current_user.id

    类似:

    before_filter :get_user_session
    
    def get_user_session
      Session.all.each do |session|
        if Marshal.load(Base64.decode64(session.data))['user_id'] == current_user.id
          # do things
        end
      end
    end
    

    【讨论】:

      猜你喜欢
      • 2020-12-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-04
      • 1970-01-01
      • 1970-01-01
      • 2011-10-28
      相关资源
      最近更新 更多