我非常了解如何在会话中存储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 %>
答案 0 :(得分:1)
在您的情况下,将id
保存在session
中需要执行一些用户操作(以选择哪个)。
您需要在params
中发送数据并在URL中显示或,在{{ 1}}方法,要求您使用request body
。如果您不想显示您的POST
是敏感数据,则需要创建一些解决方法。
我建议您使用某种加密方法在参数中传递数据,因为您主要担心的是您不希望id可见。那里有很多加密方法和库,这只是我提出的解决方案。
我创建了一个hidden_field
来接收id
,因此您不必以这种形式编写custom_route
。
encrypted_id
在视图中,将hidden_field
与get "/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
变量中。在我的解决方案中,某些事情不是必需的,例如方法cookies
或ENV
是在URL参数中发送的(它可以在另一方法的:get
中发送),但想法是一样的。我希望这个答案对您有用:如果您需要用户交互,则需要以某种方式进行交流。