I'm trying to include a simple user authentication into my application, based on a filemaker database (using the ginjo-rfm gem). After getting some ideas from Ryan Bates' Authentication from Scratch, I've written a customized version of it, but running into some problems.
When I submit my login form, I'm presented with
undefined method `find_by_username' for User:Class
The find_by_username method should be based on a column in the database called 'username', is it not?
User.rb
class User < Rfm::Base
include ActiveModel::SecurePassword
include ActiveModel::MassAssignmentSecurity
include ActiveModel::SecurePassword
has_secure_password
attr_accessible :username, :password
config :layout => 'web__SupplierContacts'
def self.authenticate(username, password)
user = find_by_username(username)
if user && user.password_hash == BCrypt::Engine.hash_secret(password, user.password_salt)
user
else
nil
end
end
end
sessions_controller.rb
class SessionsController < ApplicationController
def new
end
def create
user = User.authenticate(params[:username], params[:password])
if user && user.authenticate(params[:password])
session[:user_id] = user.id
redirect_to root_url, notice: "Logged in!"
else
flash.now.alert = "Email or password is invalid"
render "new"
end
end
def destroy
session[:user_id] = nil
redirect_to root_url, notice: "Logged out!"
end
end
I'm guessing this is a problem with my model inheriting from Rfm::Base, but I'm not sure. Any ideas?
Idea:
Is there any way to rephrase the Class.find_by_column
statement? I'm not able to do User.where(:username => "username usernamerson"
, either (returns undefined method 'where' for User:Class
).
If Rfm::Base
does not extend ActiveRecord
, then you won't be able to use the activerecord db query methods like find
, where
, etc. -- they are part of the ActiveRecord
class and only available to classes which inherit from it.
If you want to include database wrapper methods in a class which extends another class (in this case Rfm::Base
), you might have a look at DataMapper, which takes the form of a module (and thus can be included in any class). (DataMapper can be used as a replacement for ActiveRecord in Rails apps.)
Also, you've included ActiveModel::SecurePassword
twice:
class User < Rfm::Base
include ActiveModel::SecurePassword
include ActiveModel::MassAssignmentSecurity
include ActiveModel::SecurePassword
I'd delete one of those.