ruby in rails Error while confirming email in devise

156 views Asked by At

i'm using devise on rails5 to confirm email address for login. everything works well until i click the confirmation link. then it shows me this error:

NameError in Devise::ConfirmationsController#show

undefined local variable or method `signin' for #< Class:0x007fb1cbe56b48>

this is the code that causes the error:

        conditions = warden_conditions.dup
        where(conditions).where(["lower(username) = :value OR lower(email)
            = :value", { :value => signin.downcase }]).first

end

this is my model that the above code belongs to:

devise :database_authenticatable, :registerable,
     :recoverable, :rememberable, :trackable, :validatable, :confirmable
attr_accessor :signin

validates :username, :uniqueness => {:case_sensitive => false}

def self.find_first_by_auth_conditions(warden_conditions)
    conditions = warden_conditions.dup
        where(conditions).where(["lower(username) = :value OR   lower(email)
            = :value", { :value => signin.downcase }]).first
end 

can some one help me about it? and if you give me some information about how this method works?

2

There are 2 answers

1
Alter Lagos On BEST ANSWER

First thing, attr_accessor defines an instance method, not a class method, so if you call signin inside a class method like self.find_first_by_auth_conditions is going to throw you that undefined local variable or method 'signin' for #< Class:0x007fb1cbe56b48> error.

Second, your find_for_database_authentication method is incomplete. You should base according to this example:

def self.find_for_database_authentication(warden_conditions)
  conditions = warden_conditions.dup
  if login = conditions.delete(:login)
    where(conditions.to_h).where([
      "lower(username) = :value OR lower(email) = :value", 
      { :value => login.downcase }
    ]).first
  elsif conditions.has_key?(:username) || conditions.has_key?(:email)
    where(conditions.to_h).first
  end
end

I'm not sure if you already used that example as base, but if you explain what were your reasons to modify it, it would be great. I there's no reasons, use that piece of code.

2
Alexander Luna On

I post my answere to your comment here. I don't know how you handle sign in but the way I did it was in the Session Controller and Session Helper:

#Session Controller

 def create
    user = User.find_by(email: params[:session][:email].downcase)
    if user && user.authenticate(params[:session][:email].downcase)
      log_in user
      redirect_back_or user
      flash[:success] = "You are logged in"
    else
      flash[:danger] = "Wrong email or password"
      render 'new'
    end
  end

The "log_in(user)" method that I used is defined in the Session Helper.

#Session Helper

  def log_in(user)
    session[:user_id] = user.id
  end