在 sign_in 之后设计重定向并执行 POST 操作
Devise redirect after sign_in and perfom POST action
我正在使用 Devise gem & Rails 6.1 构建一个活动平台。
我在使用小型 RSVP 功能时遇到问题。
当非登录用户单击“参加”按钮时,它会将用户重定向到登录,完成后用户将重定向回上一页。但是,用户必须再次单击“参加”按钮。
我希望用户重定向回来并完成创建操作(POST 操作)
我成功地完成了重定向工作,但用户必须再次单击我不想要的“参加”按钮。我搜索了整个互联网,但 none 的解决方案有效。
我找到的壁橱解决方案来自这个博客https://blog.justinthiele.com/retaining-form-data-through-a-login-process-a/,我试图将其应用于我的应用程序但没有成功。
我认为 after_sign_in_path_for
方法中缺少某些东西。
如有任何帮助,我们将不胜感激。
更新!
调试后,我改变了一些覆盖 Devise 的方式。
我觉得我非常接近解决方案,但无法弄清楚我错过了什么。
attendee_controller.rb
def create
if !current_user
# Store the data in the session so we can retrieve it after login
session[:attendee] = params
# Redirect the user to register/login
redirect_to user_session_path
else
@attendee = current_user.attendees.build({event_id: params[:id]})
respond_to do |format|
AttendeeMailer.with(event: @attendee).notify_event_creator.deliver_now
if @attendee.save
format.html { redirect_to @attendee.event, notice: "You have successfully registered for the event!" }
format.json { render :show, status: :created, location: @attendee }
else
format.html { render :new, status: :unprocessable_entity }
format.json { render json: @attendee.errors, status: :unprocessable_entity }
end
end
end
end
app\controllers\users\sessions_controller.rb (user_session_path)
protected
def after_sign_in_path_for(resource_or_scope)
if session[:attendee].present?
new_attributes = session[:attendee]
previous_url = session[:previous_url] #defined in the show method from the events controller.
@attendee = current_user.attendees.create({event_id: new_attributes[:id]})
#clear session
session[:attendee] = nil
session[:previous_url] = nil
previous_url
else
#if there is not temp attendee in the session proceed as normal
super
end
end
events_controller.rb
def show
session[:previous_url] = request.fullpath
end
routes.rb
devise_for :users, controllers: { sessions: "users/sessions" }
resources :events do
post :attendee, to: 'attendees#create', on: :member
post :unattend, to: 'attendees#destroy', on: :member
end
在浏览量中,views\events\show.html.erb
<%= button_to 'Attend Now', attendee_event_path(@event), class:"btn btn-success btn-lg" %>
找到解决方案!
实际上有一个名为 repost
的 gem,可帮助您重定向到 POST 操作。我在我的解决方案中实现了它。
这是我应用的全部技术。在 sign-in 之后重定向,然后在登录成功时完成 POST 操作:
首先,我创建一个会话 session[:previous_url]
以供稍后用于重定向回此处。
def show
session[:previous_url] = request.fullpath #url for user to come back after signing in
...
attendee_controller.rb :我们创建 session[:attendee]
def create
if !current_user
session[:attendee] = true
redirect_to user_session_path
else
...
app\controllers\users\sessions_controller.rb (user_session_path)
protected
def after_sign_in_path_for(resource_or_scope)
if session[:attendee]
previous_url = session[:previous_url]
session[:previous_url] = nil #clear session
previous_url #going back to event page
else
super
end
end
有关 after_sign_in_path_for
方法的更多信息,请参见 Devise How-To Wiki。
previous_url
将使我们从事件中回到 show
视图。
这里是 gem 拯救世界的地方:
app\controllers\events_controller.rb
before_action :attendee?, only: :show
private
def attendee?
if session[:attendee]
session[:attendee] = nil
repost(attendee_event_path, options: {authenticity_token: :auto})
end
end
这是 gem 模板:
repost('url' , params: {}, options: {})
这里是 gem link: https://github.com/vergilet/repost
我正在使用 Devise gem & Rails 6.1 构建一个活动平台。 我在使用小型 RSVP 功能时遇到问题。
当非登录用户单击“参加”按钮时,它会将用户重定向到登录,完成后用户将重定向回上一页。但是,用户必须再次单击“参加”按钮。
我希望用户重定向回来并完成创建操作(POST 操作)
我成功地完成了重定向工作,但用户必须再次单击我不想要的“参加”按钮。我搜索了整个互联网,但 none 的解决方案有效。 我找到的壁橱解决方案来自这个博客https://blog.justinthiele.com/retaining-form-data-through-a-login-process-a/,我试图将其应用于我的应用程序但没有成功。
我认为 after_sign_in_path_for
方法中缺少某些东西。
如有任何帮助,我们将不胜感激。
更新!
调试后,我改变了一些覆盖 Devise 的方式。 我觉得我非常接近解决方案,但无法弄清楚我错过了什么。
attendee_controller.rb
def create
if !current_user
# Store the data in the session so we can retrieve it after login
session[:attendee] = params
# Redirect the user to register/login
redirect_to user_session_path
else
@attendee = current_user.attendees.build({event_id: params[:id]})
respond_to do |format|
AttendeeMailer.with(event: @attendee).notify_event_creator.deliver_now
if @attendee.save
format.html { redirect_to @attendee.event, notice: "You have successfully registered for the event!" }
format.json { render :show, status: :created, location: @attendee }
else
format.html { render :new, status: :unprocessable_entity }
format.json { render json: @attendee.errors, status: :unprocessable_entity }
end
end
end
end
app\controllers\users\sessions_controller.rb (user_session_path)
protected
def after_sign_in_path_for(resource_or_scope)
if session[:attendee].present?
new_attributes = session[:attendee]
previous_url = session[:previous_url] #defined in the show method from the events controller.
@attendee = current_user.attendees.create({event_id: new_attributes[:id]})
#clear session
session[:attendee] = nil
session[:previous_url] = nil
previous_url
else
#if there is not temp attendee in the session proceed as normal
super
end
end
events_controller.rb
def show
session[:previous_url] = request.fullpath
end
routes.rb
devise_for :users, controllers: { sessions: "users/sessions" }
resources :events do
post :attendee, to: 'attendees#create', on: :member
post :unattend, to: 'attendees#destroy', on: :member
end
在浏览量中,views\events\show.html.erb
<%= button_to 'Attend Now', attendee_event_path(@event), class:"btn btn-success btn-lg" %>
找到解决方案!
实际上有一个名为 repost
的 gem,可帮助您重定向到 POST 操作。我在我的解决方案中实现了它。
这是我应用的全部技术。在 sign-in 之后重定向,然后在登录成功时完成 POST 操作:
首先,我创建一个会话 session[:previous_url]
以供稍后用于重定向回此处。
def show
session[:previous_url] = request.fullpath #url for user to come back after signing in
...
attendee_controller.rb :我们创建 session[:attendee]
def create
if !current_user
session[:attendee] = true
redirect_to user_session_path
else
...
app\controllers\users\sessions_controller.rb (user_session_path)
protected
def after_sign_in_path_for(resource_or_scope)
if session[:attendee]
previous_url = session[:previous_url]
session[:previous_url] = nil #clear session
previous_url #going back to event page
else
super
end
end
有关 after_sign_in_path_for
方法的更多信息,请参见 Devise How-To Wiki。
previous_url
将使我们从事件中回到 show
视图。
这里是 gem 拯救世界的地方:
app\controllers\events_controller.rb
before_action :attendee?, only: :show
private
def attendee?
if session[:attendee]
session[:attendee] = nil
repost(attendee_event_path, options: {authenticity_token: :auto})
end
end
这是 gem 模板:
repost('url' , params: {}, options: {})
这里是 gem link: https://github.com/vergilet/repost