rails 3.1.3中的会话使用情况,返回错误

时间:2013-12-15 08:32:24

标签: ruby-on-rails ruby-on-rails-3 session-cookies

我正在将我的应用从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>

1 个答案:

答案 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)