如果cart_id不再存在,如何强制使会话失效?

时间:2013-12-02 11:41:45

标签: ruby-on-rails ruby-on-rails-3 session devise

我在我的应用中实现了购物车。

在我的ApplicationController.rb中,我有这个:

before_filter :initialize_cart

  def initialize_cart
    if session[:cart_id]
      @cart = Cart.find(session[:cart_id])
    else
      @cart = Cart.create
      session[:cart_id] = @cart.id
    end
  end

我正在使用Devise,并已启用:timeoutable

这些是我config/initializers/devise.rb中的配置:

  # ==> Configuration for :timeoutable
  # The time you want to timeout the user session without activity. After this
  # time the user will be asked for credentials again. Default is 30 minutes.
  config.timeout_in = 30.minutes

  # If true, expires auth token on session timeout.
  config.expire_auth_token_on_timeout = true

问题在于我偶尔想要扫旧车。就目前而言,一旦购物车暂时无法访问,它就会被删除。

然而,当用户尝试登录时 - 如果他们暂时没有清除cookie - 他们会收到此错误:

ActiveRecord::RecordNotFound at /
Couldn't find Cart with id=51

我检查了会话对象的创建或更新时间戳,但它没有 - 所以我无法检查会话状态并删除会话,如果超过30分钟或其他什么。

这是会话对象的样子:

>> session
=> {"session_id"=>"57bkhjadksjfhaksjdhfca", "cart_id"=>51, "_csrf_token"=>"3823j42&*&@#lkjM+wKkagdabskdjfhba="}

我如何检查会话是否是最近的(比如用户 - 已登录和未登录 - 在过去一小时内完成了某项操作)然后如果不是则将其销毁?

或者如何以其他方式解决此问题?

2 个答案:

答案 0 :(得分:1)

目前,当您初始化购物车时,您正在执行此操作:

def initialize_cart
  if session[:cart_id] && Cart.find(session[:cart_id])
    @cart = Cart.find(session[:cart_id])
  else
    @cart = Cart.create
    session[:cart_id] = @cart.id
  end
end

我认为你可以试试这个:

def initialize_cart
  if session[:cart_id] && Cart.find(session[:cart_id]).exists?
    @cart = Cart.find(session[:cart_id])
  else
    @cart = Cart.create
    session[:cart_id] = @cart.id
    session[:cart_modified] = @cart.updated_at
  end
end

然后访问session[:cart_modified] param以执行您需要的操作。您可以尝试的另一件事(可以说比我的第一个解决方案好得多)是find_or_create_by

def initialize_cart
  @cart = Cart.find_or_create_by(session[:cart_id])
end

答案 1 :(得分:1)

我就是这样做的。

def initialize_cart
    begin
      @cart = Cart.find(session[:cart_id])
    rescue ActiveRecord::RecordNotFound
      flash.now = "Your cart was not found." # or whatever
      @cart = Cart.create
      session[:cart_id] = @cart.id
    end
end