如何将从关联数组中选择的 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
中发送另一种方法),但思路是一样的。我希望这个答案对你有用:如果你需要用户交互,你需要以某种方式进行交流。
我非常了解如何在会话中存储 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
中发送另一种方法),但思路是一样的。我希望这个答案对你有用:如果你需要用户交互,你需要以某种方式进行交流。