Rails 会话存储模型对象

Posted

技术标签:

【中文标题】Rails 会话存储模型对象【英文标题】:Rails session store model object 【发布时间】:2016-07-26 07:22:11 【问题描述】:

我使用 session 来存储我的购物车对象

在我的购物车模型中

def initialize
    @items = Array.new
end

def clean
    @items = Array.new
end 

我想使用 session 来存储整个购物车对象,所以我可以使用上面的方法

喜欢这个

@cart = session[:cart] ||= Cart.new

但我的@cart 输出很奇怪

第一次运行输出

<%= @cart %>
#<Cart:0x007efc844d3af0>

<% @cart.clean %>
true

一切正常,但第二次输出对象的内容

<%= @cart %>
"items"=>[]

<% @cart.clean %>
undefined method `clean'

会话可以存储整个对象吗?

还是我做错了什么?

谢谢。

编辑:

<% session[:cart] = Cart.new %>
<%= session[:cart] %>
#<Cart:0x007efc868be0a0>

<% session[:cart] = session[:cart] ||= Cart.new %>
<%= session[:cart] %>
#<Cart:0x007efc868be0a0> #Because session[:cart] does not exist
<% session[:cart] = session[:cart] ||= Cart.new %>
<%= session[:cart] %>
"items"=>[] #Session does not store the cart object but store the cart object's content

编辑 2:

<% @cart = session[:cart] ||= Cart.new %>
<%= @cart %> #session[:cart] is nil so print Cart.new
<br>
<% session[:cart] = Cart.new %>
<% @cart = session[:cart] ||= Cart.new %>
<%= @cart %> #session[:cart] isn't nil so print session[:cart]

我得到两个输出都是 Cart 对象

当我刷新页面并运行相同的代码时

<% @cart = session[:cart] ||= Cart.new %>

@cart 应该是 session[:cart] 因为 session 不是 nil 并且 session[:cart] 应该是 Cart 对象但它输出 ""items"=>[]"

编辑 3:

第一次:

<%= session[:cart] %>
-> nil
<% session[:cart] = Cart.new %>
<%= session[:cart] %>
-> <Cart:0x00000007c112c0>

第二次:

<%= session[:cart] %>
-> "items"=>[] #Why it isn't a Cart object after I refresh?
<% session[:cart] = Cart.new %>
<%= session[:cart] %>
-> <Cart:0x00000007c112c0>

【问题讨论】:

会话可以存储购物车对象吗?我想让session[:cart].clean@cart.clean 都可以工作,谢谢。 在会话中存储对象不是一个好主意,请参阅***.com/questions/1095714/…。这个线程讨论了它的陷阱。如果您坚持在会话中存储对象,则必须通过将参数传递给 Cart.new(session[:cart]) 或类似的东西来重建它,因为会话会序列化对象并存储它。希望这会有所帮助。 @Shishir 感谢您的帮助,我不想将购物车项目存储到数据库中,所以我将购物车对象放到会话中,购物车对象是一个小数组来存储产品 id 和数量。我不明白为什么我刷新页面我得到不同的会话输出。请参阅编辑 2,谢谢。 第一次渲染,它在服务器端,它们仍然是 ruby​​ 对象。刷新时,会话从客户端获取并反序列化。请参阅此***.com/questions/3804209/… 了解更多信息。 @Shishir 非常感谢!我完全明白。那么如何在没有数据库表的情况下存储 Cart 对象呢? 【参考方案1】:

始终使用购物车对象。从会话初始化它,执行操作,最后将它序列化回会话。

    class Cart
      def initialize(params=)
        @items = params[:items] || []
      end
    end

    controller:
    @cart = Cart.new(session[:cart])
    //do operations on cart

    session[:cart] = @cart

【讨论】:

以上是关于Rails 会话存储模型对象的主要内容,如果未能解决你的问题,请参考以下文章

Rails:如何在会话中存储数据?

在 Rails 中存储持久会话数据而不影响正常会话过期

会话存储在 Rails 中的啥位置?

Rails 最好的安全会话存储?

Ruby on Rails 中的会话如何工作?

在 Rails api 应用程序中存储会话