ruby-on-railsrubysession-variablesacts-as-paranoid

Why does acts_as_paranoid break my model?


I recently added the "paranoid" gem to the User model of my project. This model also uses "has_secure_password"; which works perfectly until I place "acts_as_paranoid" at the top of my User model. Now all I'm getting the following argument error:

Started GET "/users/8/edit" for 127.0.0.1 at 2014-09-16 20:57:48 -0400
Processing by UsersController#edit as HTML
  Parameters: {"id"=>"8"}
Completed 500 Internal Server Error in 5ms

ArgumentError (wrong number of arguments (0 for 1)):
  app/models/user.rb:19:in `hash'
  app/helpers/sessions_helper.rb:25:in `current_user'
  app/helpers/sessions_helper.rb:11:in `signed_in?'
  app/helpers/sessions_helper.rb:33:in `signed_in_user'

Any ideas would be greatly appreciated.

Here is my user model:

class User < ActiveRecord::Base
  acts_as_paranoid
  before_save { self.email = email.downcase }
    before_create :create_remember_token

    validates :name, presence: true, length: { maximum: 50 }
    VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
    validates :email, presence: true, format: { with: VALID_EMAIL_REGEX },
                    uniqueness: { case_sensitive: false }
    validates :password, length: { minimum: 6 }
    validates_inclusion_of :status, :in => ['active', 'inactive']
    has_secure_password


    def User.new_remember_token
        SecureRandom.urlsafe_base64
    end

    def User.hash(token)
        Digest::SHA1.hexdigest(token.to_s)
    end

private

    def create_remember_token
      self.remember_token = User.hash(User.new_remember_token)
    end

end

And here is my session helper:

module SessionsHelper

  def sign_in(user)
    remember_token = User.new_remember_token
    cookies.permanent[:remember_token] = remember_token
    user.update_attribute(:remember_token, User.hash(remember_token))
    self.current_user = user
  end

  def signed_in?
    !current_user.nil?
  end


  def current_user=(user)
    @current_user = user
  end

  def current_user
    @current_user     
  end

   def current_user
    remember_token = User.hash(cookies[:remember_token])
    @current_user ||= User.find_by(remember_token: remember_token)
  end

  def current_user?(user)
    user == current_user
  end

  def signed_in_user
    unless signed_in?
      store_location
      redirect_to signin_url, notice: "Please sign in."
    end
  end

   def sign_out
    self.current_user = nil
    cookies.delete(:remember_token)
  end

  def redirect_back_or(default)
    redirect_to(session[:return_to] || default)
    session.delete(:return_to)
  end

  def store_location
    session[:return_to] = request.url if request.get?
  end

end

Solution

  • User.hash by convention of its parent class takes no arguments and should return a Fixnum.

    It is used for object comparison by other classes throughout the Ruby language, for example when looking up the value of a key in a Hash. If a.eql?(b), then a.hash == b.hash must be true as well.

    The best way to fix the issue is to rename your hash method to something else, not to get in the way of the Ruby conventions.