我正在将我的应用从rails 2.3.11升级到3.2.x.一切顺利,直到3.1.x我遇到会话处理问题。之前我已经使用cookie进行会话处理,但现在有一个问题,我是否可以使用ActiveModel来处理会话?????
其次,虽然仍在使用cookie,但我发现这个不可避免的未定义方法错误。有任何建议可以解决这个错误????
这是我的代码 -
会话控制器:
class SessionsController < ApplicationController
def new
@title = "Sign in"
end
def create
@title = "create session"
user = User.authenticate(params[:session][:name], params[:session][:password])
if user.nil?
flash.now[:error] = "Invalid username/password combination."
@title = "Sign in"
render 'new'
else
sign_in user
@partner = Partner.find(:first, :conditions => [ "user_id = ?", user.id])
logger.info "---------User loggin: " + current_user.name
redirect_back_or samplings_url
end
end
def destroy
@title = "Sign out"
logger.info "---------User log OUT: " + current_user.name
sign_out
redirect_to root_path
end
end
用户模型:
class User < ActiveRecord::Base
attr_accessor :password
attr_accessible :name, :email, :password
EmailRegex = /\A[\w+\-._]+@[a-z\d\-.]+\.[a-z]+\z/i
validates_presence_of :name, :email
validates_length_of :name, :maximum => 50
validates_format_of :email, :with => EmailRegex
validates_uniqueness_of :email, :case_sensitive => false
has_many :microposts
validates_confirmation_of :password
validates_presence_of :password
validates_length_of :password, :within => 1..40
before_save :encrypt_password
def self.authenticate(name, submitted_password)
username = self.where(name: name)
return nil if username.nil?
return username if username.encrypted_password == encrypt(submitted_password)
end
def remember_me!
self.remember_token = encrypt("#{salt}--#{id}--#{Time.now.utc}")
save(validate=false)
end
private
def encrypt_password
unless password.nil? #due to def remember_me! method during sign in function call
self.salt = make_salt
self.encrypted_password = encrypt(password)
end
end
def encrypt(string)
secure_hash("#{salt}#{string}")
end
def make_salt
secure_hash("#{Time.now.utc}#{password}")
end
def secure_hash(string)
Digest::SHA2.hexdigest(string)
end
end
UserController中:
class UsersController < AuthController
before_filter :authenticate, :only => [:index, :edit, :update]
before_filter :correct_user, :only => [:new, :create, :destroy]
before_filter :modify_user, :only => [:edit, :update]
filter_parameter_logging :password
def index
@users = User.all
@title = "users"
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => @users }
end
end
def show
@user = User.find(params[:id])
@title = @user.name
respond_to do |format|
format.html # show.html.erb
format.xml { render :xml => @user }
end
end
def new
redirect_to signin_path
if !current_user?(@user)
flash[:notice] = "Only the partner who create the risorse can modify it."
end
end
def create
@title = "sign up user"
@user = User.new(params[:user]) #hash of user attributes
if @user.save
sign_in @user
flash[:success] = "Welcome to the microaqua web application!"
redirect_to @user #equal as user_path(@user)
else
@title = "Sign up"
render 'new'
end
end
# GET /users/1/edit
def edit
@title = @user.name #"user"
end
def update
@title = @user.name #"user"
if @user.update_attributes(params[:user])
flash[:success] = "Profile updated."
redirect_to @user
else
@title = "Edit user"
render 'edit'
end
end
def destroy
redirect_to users_path
end
private
def correct_user
@user = User.find(params[:id])
reroute() unless signed_in_and_master?
end
def modify_user
@user = User.find(params[:id])
reroute() unless (current_user?(@user) or signed_in_and_master?)
end
def reroute()
flash[:notice] = "Only the partner can modify his own profile."
redirect_to(user_path(@user))
end
end
错误:
NoMethodError in SessionsController#create
undefined method `encrypted_password' for #<ActiveRecord::Relation:0x00000003632038>
答案 0 :(得分:1)
.where
总是返回一个数组。以下是在用户模型中抛出错误的代码:
def self.authenticate(name, submitted_password)
username = self.where(name: name)
return nil if username.nil?
return username if username.encrypted_password == encrypt(submitted_password)
end
您在数组上调用.encrypted_password
。将代码更改为:
def self.authenticate(name, submitted_password)
username = self.where(name: name).first
return nil if username.nil?
return username if username.encrypted_password == encrypt(submitted_password)
end
如果可以获得多个具有相同名称的用户,那么您应该遍历数组并检查每个结果。
至于将会话存储在数据库中,请查看此SO问题:Rails 3: Storing Session in Active Record (not cookie)