你错误地接近这个。您正在处理登录并检查是否有人在同一步骤中登录。
考虑使用 session_controller 来处理所有注册/登录/注销逻辑,例如:
class SessionsController < ApplicationController
def new # this will be /login
session[:return_to] = params[:returnto] unless params[:returnto].nil?
redirect_to "/auth/facebook"
end
def create # this will be the callback after the user is authenticated
auth_token = request.env["omniauth.auth"]["credentials"]["token"]
# you'll need to write this based on your app's requirement.
# Find a user or create one if he doesn't exist yet.
user = User.find_or_create_authenticated_user(auth_token)
if user.present?
session[:user_id] = user.id # this stores the current user's id in your session and lets Rails remember him for you.
redirect_to return_or(products_url) # see below for the usage of return_or
return
end
redirect_to root_url, alert: 'User not found or invalid'
end
def destroy # /logout
session[:user_id] = nil
redirect_to root_url
end
end
#routes.rb
match '/logout' => 'sessions#destroy', :as => :logout
match '/login' => 'sessions#new', :as => :login
match '/auth/facebook/callback' => 'sessions#create'
然后,在ApplicationController
你设置几个辅助方法:
class ApplicationController < ActionController::Base
protected
# Use this in your views and controllers to get
# a handle of the user that is currently logged in.
# it will return nil if there is no user logged in.
def current_user
@current_user ||= User.find(session[:user_id]) if session[:user_id]
end
helper_method :current_user
# Use this to check wether a user is logged in.
# returns true if there is a user, false otherwise.
def logged_in?
!current_user.nil?
end
helper_method :logged_in?
# Block access to controllers or actions based on
# wether there's a user or not.
def require_login
unless logged_in?
# if we need the user to log in, we send him on his way
# but send him back to the current page afterwards.
session[:return_to] = request.fullpath
redirect_to root_url(subdomain: false), :alert => "Please login"
end
end
# When a user is not logged in, but you send him to log in,
# you can force him to return to the url he was in or if nothing
# was set go to a standard path.
# See this being set up in SessionsController#new and in require_login and then
# being used in SessionsController#create
def return_or(path)
session.delete(:return_to) || path
end
helper_method :return_or
end
这些辅助方法在所有控制器中都可用,因为它们都继承自ApplicationController
. 然后,您可以告诉您PostsController
发送未登录的用户去登录,然后他们将返回到 PostsController。
然后解决您仅在身份验证后保存帖子的要求:您确实创建帖子,保存它,但仅在用户通过身份验证后将其更新为公开,或者您将帖子的内容存储在会话中并恢复它们用户通过身份验证后:
class PostsController < ApplicationController
def new
@post = Post.new(session[:post_params] || {})
end
def create
if logged_in?
@post = Post.create(params[:post])
# ... etc
else
session[:post_params] = params[:post]
session[:return_to] = new_post_path
end
end
end
请注意,这是一种相当脆弱的方法。我宁愿建议实际创建Post
,将其标记为尚未公开并仅将帖子存储id
在会话中。身份验证后,您可以找到该 post_id,从中重新创建对象,将其状态设置为 public 并将其与 current_user 关联。