在我的Rails 3应用程序中,我在注册过程中被重定向到登录。注册的步骤应该是:
/signup/join
)/profiles/:id
)我在第1步之后被重定向到/login
,我在重定向后看到302错误。如果我在before_filter :authenticate
中注释掉profiles_controller.rb
并重做上述步骤,则不会重定向到/signup/join
,但我收到以下错误:
NoMethodError in ProfilesController#edit
undefined method `profile' for nil:NilClass
我指出了Profiles#edit
行动的第一行:
def edit
@profile = user.profile
if @profile.higher_ed?
higher_ed = HigherEd.find_or_create_by_name(:name => @profile.higher_ed)
end
if @profile.employer?
employer = Employer.find_or_create_by_name(:name => @profile.employer)
end
render :layout => "join_form"
end
我一直试图在我的应用程序中实现CanCan,所以我认为这就是原因。但是我注释掉了我的整个ability.rb
文件,问题仍然存在。我显然想在不评论before_filter
的情况下弄清楚如何解决这个问题。所以,如果有人有想法,我会非常感激。由于我正在处理依赖于current_user
的CanCan,因此我将从current_user
中application_controller.rb
的定义开始:
protected
# Returns the currently logged in user or nil if there isn't one
def current_user
return unless session[:user_id]
@current_user ||= User.find_by_id(session[:user_id])
@current_user ||= User.find_by_auth_token!(cookies[:auth_token]) if cookies[:auth_token]
end
# Make current_user available in templates as a helper
helper_method :current_user
这是我的users_controller.rb
:
class UsersController < ApplicationController
before_filter :authenticate, :only => [:edit, :update, :index]
layout "application"
def new
@user = User.new
@user.profile = Profile.new
if logged_in?
redirect_to current_user.profile
end
end
def create
@user = User.new(params[:user])
if @user.save
session[:user_id] = @user.id
redirect_to join_path, :notice => 'User successfully added.'
UserMailer.registration_confirmation(@user).deliver
else
render :action => 'new'
end
end
我的profiles_controller.rb
:
class ProfilesController < ApplicationController
#before_filter :authenticate, :only => [:edit, :update]
helper_method :find_or_create_group
layout "application", :except => [:edit, :show]
def new
@profile = Profile.new(params[:profile])
end
def create
@profile = Profile.new(params[:profile])
if @profile.save
redirect_to @user.profile, :notice => 'User successfully added.'
else
render :new
end
if @profile.higher_ed?
HigherEd.find_or_create_by_name(:name => @profile.higher_ed)
end
if @profile.employer?
Employer.find_or_create_by_name(:name => @profile.employer)
end
if @profile.job_title?
JobTitle.find_or_create_by_name(:name => @profile.job_title)
end
if @profile.high_school?
HighSchool.find_or_create_by_name(:name => @profile.high_school)
end
end
def user
@user = current_user
end
def edit
@profile = user.profile
if @profile.higher_ed?
higher_ed = HigherEd.find_or_create_by_name(:name => @profile.higher_ed)
end
if @profile.employer?
employer = Employer.find_or_create_by_name(:name => @profile.employer)
end
render :layout => "join_form"
end
我的sessions_controller.rb
:
class SessionsController < ApplicationController
def new
end
def create
if user = User.authenticate(params[:email].downcase, params[:password])
session[:user_id] = user.id
cookies.permanent[:auth_token] = user.auth_token
if user.profile.higher_ed?
redirect_to user.profile, :notice => "Logged in successfully"
else
redirect_to join_path, :notice => "Logged in successfully"
end
else
flash.now[:alert] = "Invalid login/password. Try again!"
render :action => 'new'
end
end
def destroy
reset_session
cookies.delete(:auth_token)
redirect_to root_path, :notice => "You successfully logged out"
end
end
CanCan的ability.rb
:
class Ability
include CanCan::Ability
def initialize(user)
user ||= User.new guest user
if user.role? :admin
can :manage, :all
else
can :manage, :all
end
end
end
我的routes.rb
:
match "/signup/join" => "profiles#edit", :as => 'join'
答案 0 :(得分:3)
@profile = user.profile
尝试将上述行更改为
@profile = @current_user.profile
或
@profile = current_user.profile
这个问题与cancan无关,而是与你的控制器中的“user”nil有关。
答案 1 :(得分:0)
我通过重新修改current_user
逻辑来实现它。现在是:
def current_user
@current_user ||= lookup_user
end
def lookup_user
if cookies[:auth_token]
User.find_by_auth_token!(cookies[:auth_token])
elsif session[:user_id]
User.find_by_id(session[:user_id])
end
end
这似乎已经成功了。