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

how can i store an id selected from an association array in a rails session variable?

我非常了解如何在会话中存储 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 %>

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

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

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

我创建了一个 custom_route,它将接收 encrypted_id,因此您不必在表格中写 hidden_field

get "/set_id/:encrypted_id" => "your_controller#set_encrypted_id", as: :set_id_route

并且在视图中,沿 MessageEncryptor 使用 custom_route,如下所示:

<% 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 %>

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

然后在你想要接收请求的控制器中解密它并在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

我写了这个阅读和设置 cookies 的示例,以便您轻松重现它,但它们应该写在您的数据库或 ENV 变量中。在我的解决方案中,有些东西不是必需的,比如方法是 :get 或者 encrypted_id 在 URL 参数中发送(它可以在 request body 中发送另一种方法),但思路是一样的。我希望这个答案对你有用:如果你需要用户交互,你需要以某种方式进行交流。