【问题标题】:Session usage in rails 3.1.3, returning errorsrails 3.1.3 中的会话使用,返回错误
【发布时间】:2013-12-15 19:40:12
【问题描述】:

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

用户控制器:

     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>

【问题讨论】:

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


    【解决方案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)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-02-03
      • 1970-01-01
      • 2017-08-25
      • 1970-01-01
      • 2016-11-06
      • 1970-01-01
      • 1970-01-01
      • 2011-01-26
      相关资源
      最近更新 更多