在覆盖Devise::SessionsController
时,我无法获取实例变量。
当未经身份验证的用户将商品添加到购物车时,我想将其重定向到登录页面并在经过身份验证后应用添加。
1。我将item_id
作为网址参数传递:
localhost:3000/user_accounts/sign_in?item_id=42
<%= form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| %>
<%= f.hidden_field :item_id, value: params[:item_id] || @item_id %>
...
<% end %>
&#13;
当Rails启动表单流时,URL参数将被删除:
之前:
localhost:3000/user_accounts/sign_in?item_id=42
后:
localhost:3000/user_accounts/sign_in
当用户未通过身份验证时,我不想丢失item_id,因此我确保@item_id
作为实例变量公开,因此我可以将其注入表单。
然而,失败时,Rails(?)/ Devise(?)/ Warden(?)似乎清除了实例变量(出于安全原因?)。因此,@item_id
为nil
。
请注意,在用户成功进行身份验证(通过URL参数)时效果很好。此外,我在注册过程中使用了这种相同的技术,它在成功(URL参数)和失败(实例变量)的情况下都有效。
这是我对SessionsController的实现:
class MySessionsController < Devise::SessionsController
def create
@item_id = parse_id(params[:user_account][:item])
super do |account|
add_to_cart(account, @item_id) if @item_id
end
flash.delete(:notice)
end
end
你知道我怎么解决这个问题吗?
我也愿意接受替代方案。
答案 0 :(得分:0)
我错了。 Rails,Devise和Warden并没有对我的实例变量做一些阴暗的事情。我发现了重定向,解释了为什么上下文丢失了。
最后,我使用cookie来解决问题,正如@nattfodd所说的那样。这是微不足道的,我不知道为什么我没有想到它。
class MySessionsController < Devise::SessionsController
def create
item_id = parse_id(cookies.encrypted[:item])
super do |account|
add_to_cart(account, item_id) if item_id
cookies.encrypted[:item] = ""
end
flash.delete(:notice)
end
end
清洁,没有黑客。好。