Fellow Stranger
Fellow Stranger

Reputation: 34013

Cannot replace dynamic finder with .where query

In a sessions controller I'm unsuccessfully trying to replace a ".find_by_email(params[:email])" with .where(email: params[:email]), and validating the password with Rails built-in has_secure_password. While the former works, the latter results in a caught exception:

undefined method `authenticate' for #<ActiveRecord::Relation:0x0000010384e690>

This is the complete code in the controller that doesn't work:

class SessionsController < ApplicationController def new end

def create
  user = User.where(email: params[:email])
  if user && user.authenticate(params[:password])
    session[:user_id] = user.id
    redirect_to texts_path, notice: "Logged in!"
  else
    render "new"
  end
end

end

Upvotes: 0

Views: 109

Answers (2)

Noz
Noz

Reputation: 6346

The authenticate is an instance method of the User class, however where returns an assortment of these objects within an ActiveRecord::Relation which doesn't know about this method. That code previously worked with the find_by_email method as that returns a single User object. To fix you can change this line:

user = User.where(email: params[:email])

to:

user = User.where(email: params[:email]).first

Upvotes: 1

boulder
boulder

Reputation: 3266

You only need to make a very small change

user = User.where(email: params[:email]).first

As Cyle mentioned, you need a single element, not the array returned by where.

Upvotes: 1

Related Questions