Devise is one of the more polarising libraries out there in the Rails ecosystem — you either love it or hate it. I'm a fan; having used it for multiple projects throughout it's evolution and giving a few alternatives a try (including rolling my own), I can't really fault it.
One thing about it that does irk me, however, is the use of the
#devise_controller? method and the pattern of customising it's behaviour by putting code in
If you follow the official how-to on allowing users to login using either username or password, you'll end up with something like this in your
before_filter :configure_permitted_parameters, :if => :devise_controller? protected def configure_permitted_parameters # ... end
This logic is needed for only a handful of actions on one controller (
DeviseController), yet we end up with a
before_filter that checks
#devise_controller? before every action in your application. Admittedly the consequences of this are minimal, but it's not a good pattern to repeat and is generally bad object-oriented design.
Thanks to the power of Ruby, and the syntactic sugar provided by
ActiveSupport::Concern, we have a nice alternative:
# config/initializers/devise.rb module MyPermittedParameters extend ActiveSupport::Concern included do before_filter :configure_permitted_parameters end protected def configure_permitted_parameters ... end end DeviseController.send :include, MyPermittedParameters
While we're picking on the above-linked guide, why not use Arel instead of raw SQL when overriding
def self.find_first_by_auth_conditions(warden_conditions) conditions = warden_conditions.dup if login = conditions.delete(:login) where(conditions). \ where(arel_table[:username].lower.eq(login.downcase).or( arel_table[:email].lower.eq(login.downcase))).first else where(conditions).first end end