如何在Rails会话变量中存储从关联数组中选择的ID?

时间:2018-10-25 19:55:03

标签: ruby-on-rails ruby session session-variables

我非常了解如何在会话中存储ID。您只需进入控制器并执行

@object = Object.find_by(params[:id)
session[:first_object] = @object 

但是如果我的视图中有一堆不同的对象,而只需要将一个传递给会话该怎么办?我不能使用hidden_fields。通常,我会将其作为参数传递给form_for,但我希望对象ID不显示在url中。

<% @owned_objects.each do |obj| %>
 <%= form_for [obj, @wizard], as: :wizard, url: object_one_wizard_path(obj) do |f| %>
 bla bla
<% end %>

1 个答案:

答案 0 :(得分:1)

在您的情况下,将id保存在session中需要执行一些用户操作(以选择哪个)。

您需要在params中发送数据并在URL中显示,在{{ 1}}方法,要求您使用request body。如果您不想显示您的POST是敏感数据,则需要创建一些解决方法。

我建议您使用某种加密方法在参数中传递数据,因为您主要担心的是您不希望id可见。那里有很多加密方法和库,这只是我提出的解决方案。

我创建了一个hidden_field来接收id,因此您不必以这种形式编写custom_route

encrypted_id

在视图中,将hidden_fieldget "/set_id/:encrypted_id" => "your_controller#set_encrypted_id", as: :set_id_route 一起使用,如下所示:

custom_route

该ID将在URL中发送,但无法读取。

然后在要接收该请求的控制器中解密该请求并将其设置在MessageEncryptor中。

<% cookies[:salt] = SecureRandom.urlsafe_base64(32) %>
<% cookies[:pass] = 'some_password' %>
<% key = ActiveSupport::KeyGenerator.new(cookies[:pass]).generate_key(cookies[:salt], 32) %>
<% crypt = ActiveSupport::MessageEncryptor.new(key) %>
<% @owned_objects.each do |obj| %>
  <%= form_for [obj, @wizard], 
               url: set_id_route(encrypted_id: crypt.encrypt_and_sign(obj.id)), # Or however you send the id
               as: :wizard, method: :get do |f| %>
      bla bla
      <%= f.submit %>
  <% end %>
<% end %>

我编写了这个示例,以供您读取和设置session以便于轻松重现,但应将它们写在您的数据库或def set_encrypted_id key = ActiveSupport::KeyGenerator.new(cookies[:pass]).generate_key(cookies[:salt], 32) crypt = ActiveSupport::MessageEncryptor.new(key) session[:id] = crypt.decrypt_and_verify params[:encrypted_id] render json: { session_id: 'ok' } end 变量中。在我的解决方案中,某些事情不是必需的,例如方法cookiesENV是在URL参数中发送的(它可以在另一方法的:get中发送),但想法是一样的。我希望这个答案对您有用:如果您需要用户交互,则需要以某种方式进行交流。