Customizing User login with Authlogic: find_by_login_method

This post would be redundant especially when Devise is the “in” thing but I love the minimality of Authlogic and I’m sure over time I’ll grow to like Devise but for now Authlogic does everything I want.

In a scenario where you want Authlogic to find Users from a subset of users while adhering to a specific condition that you set (for instance: login users from a set of users who have active accounts), you would need to define some kind of condition or scope to find these users.

A simple configuration that Authlogic allows is

class UserSession < Authlogic::Session::Base
  find_by_login_method  :find_by_activated_user
end

The find_by_login_method identifies the class method that would be called upon the User model to find the user.

In user.rb

  def self.find_by_activated_user(email)
    self.find_by_email_and_activated(email, true)
  end

where activated is a boolean attribute that identifies if a user has been blocked from using the site.

Understanding the &: Ruby syntax

The symbol.to_proc method was something I hesitated to use for a long time because I found it be unclear and something that went against Ruby’s clear and easy to understand syntax. Though this subject is old news its something I’ve found that goes against ruby’s clarity over cleverness standards.

The Proc Object

A Proc object is block code that can be accessed as an Object. A proc when defined associates itself to a set of variables (local) and can be used at later point of time in the context of those variables

The official definition

So lets consider a simple example

def test(&block)
   puts  block.class.to_s  # "Proc"
   block.call  # would execute the block of code
end

test{puts "Bazingaaa" } # Bazingaa

So the result would be

"Proc"
Bazingaa

Its just a block of code that you can run whenever you want.

Now Ruby symbols have a to_proc method which allows you to convert a symbol to a proc.

 :test.methods.include?('to_proc')
 => true

:someSymbol.to_proc # Would yield a proc object #

Now if we go through the array.map code from the Ruby library, we see that it executes a block of code on each element of the array.

  array.map     {|item| block }  -> an_array
 p  [1,2,3,4,5].map(Proc.new{ |x| x + 1 }) # 2,3,4,5,6

If we create a simple block and pass it to the map method it would execute the code in the block for each element.

So the &: is actually &symbol and not &:something. Since the conversion of the to_proc method is not explicit the code

p [1,2,3,4,5].map(&:to_i) 

is actually

p [1,2,3,4,5].map(&(Proc.new{|x| x.to_i}))

The to_proc method as found in Rails 2.3.5

  def to_proc
      Proc.new { |*args| args.shift.__send__(self, *args) }
    end

Hope this helps someone