繁体   English   中英

在将红宝石对象保存到会话中后,为什么将其转换为哈希,我如何保留其作为对象的状态?

[英]Why is my ruby object being converted to a Hash after saving it in a session and how do I retain it's status as an object?

我有一个要保存到会话中的Board类的实例。 在我提交表单并尝试从会话中检索Board对象之后,session [:board]现在是一个哈希。 演示和解释起来可能更容易,所以这里是我的代码。

我的控制器中的新方法:

def new
    session[:player] = "X"
    session[:board] = Board.new
    @board = session[:board]
end

这是视图:

<div id="board">
  <%= simple_format(@board.render) %>

</div>


<h2>Choose the column you would like to drop a piece in</h2>


  <%= form_tag( drop_piece_path, :method => "post" ) do %>

    <% 7.times do |col| %>
      <%= label_tag col %>
      <% unless @board.column_full?(col) %>
        <%= radio_button_tag(:column, col) %>
      <% end %>
    <% end %>


    <%= submit_tag("Enter move")%>
  <% end %>

<%= @board.class %>

在这一点上,@ board.class是我期望的董事会。

将表单提交到以下drop_piece方法之后:

def drop_piece
    @board = session[:board]
    @board.drop_piece(params[:column].to_i, session[:player])
    save_session(@board)

end

我收到此错误:

undefined method `drop_piece' for #<Hash:0x007fe40bd070e0>

@ board.class和session [:board] .class都导致哈希。 drop_piece是我的Board类的一种方法,因此我不能在Hash上调用它是有意义的。

因此,在我的Board对象被转换为哈希值的过程中。 也许我只是在滥用会话,但是我已经尝试搜索该问题,但无法提出任何建议。 谢谢您的帮助。

您无意将随机对象填充到Rails会话中。 会话本质上是字符串的键值存储,因此您所看到的是将对象自动展平为会话可以管理的形式。

您最好先将对象转换为JSON,然后再将其传递给会话,并在获取对象后对其进行解码。 在您的情况下,您也可以只创建一个构造函数,以将Board对象的所有必要字段作为参数,并在接收器方法中重建Board或使用Ruby的Marshal模块来获取所需的内容。

您还可以将开发板存储在更持久的内容(缓存甚至数据库)中,只需将ID传递给会话即可。 然后,接收者可以根据ID检索行并重建对象。

当您使用cookie会话存储(默认)时,由于rails 4.1的默认行为是使用JSON序列化会话数据。 Rails的早期版本使用的是Marshal,它确实允许存储任意的红宝石类,但是涉及到Marshal的许多红宝石安全漏洞使人们警惕使用它。 当较新版本的应用程序加载由较旧版本创建的数据时,您还存在错误的风险。

您可以通过设置恢复为旧的行为

Rails.application.config.action_dispatch.cookies_serializer = :marshal

或通过使用其他会话存储。 但是,我建议您改为坚持在会话中存储简单数据,或者至少要明确存储的内容,而不要隐式地进行此转换。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM