module Sorcery::Model

This module handles all plugin operations which are related to the Model layer in the MVC pattern. It should be included into the ORM base class. In the case of Rails this is usually ActiveRecord (actually, in that case, the plugin does this automatically).

When included it defines a single method: 'authenticates_with_sorcery!' which when called adds the other capabilities to the class. This method is also the place to configure the plugin in the Model layer.

Public Instance Methods

authenticates_with_sorcery!() click to toggle source
# File lib/sorcery/model.rb, line 10
def authenticates_with_sorcery!
  @sorcery_config = Config.new

  extend ClassMethods # included here, before submodules, so they can be overriden by them.
  include InstanceMethods
  include TemporaryToken

  include_required_submodules!

  # This runs the options block set in the initializer on the model class.
  ::Sorcery::Controller::Config.user_config.tap { |blk| blk.call(@sorcery_config) if blk }

  define_base_fields
  init_orm_hooks!

  @sorcery_config.after_config << :add_config_inheritance if @sorcery_config.subclasses_inherit_config
  @sorcery_config.after_config.each { |c| send(c) }
end

Private Instance Methods

define_base_fields() click to toggle source
# File lib/sorcery/model.rb, line 31
def define_base_fields
  class_eval do
    sorcery_config.username_attribute_names.each do |username|
      sorcery_adapter.define_field username, String, length: 255
    end
    unless sorcery_config.username_attribute_names.include?(sorcery_config.email_attribute_name)
      sorcery_adapter.define_field sorcery_config.email_attribute_name, String, length: 255
    end
    sorcery_adapter.define_field sorcery_config.crypted_password_attribute_name, String, length: 255
    sorcery_adapter.define_field sorcery_config.salt_attribute_name, String, length: 255
  end
end
include_required_submodules!() click to toggle source

includes required submodules into the model class, which usually is called User.

# File lib/sorcery/model.rb, line 46
def include_required_submodules!
  class_eval do
    @sorcery_config.submodules = ::Sorcery::Controller::Config.submodules
    @sorcery_config.submodules.each do |mod|
      # TODO: Is there a cleaner way to handle missing submodules?
      # rubocop:disable Lint/HandleExceptions
      begin
        include Submodules.const_get(mod.to_s.split('_').map(&:capitalize).join)
      rescue NameError
        # don't stop on a missing submodule. Needed because some submodules are only defined
        # in the controller side.
      end
      # rubocop:enable Lint/HandleExceptions
    end
  end
end
init_orm_hooks!() click to toggle source

add virtual password accessor and ORM callbacks.

# File lib/sorcery/model.rb, line 64
def init_orm_hooks!
  sorcery_adapter.define_callback :before, :validation, :encrypt_password, if: proc { |record|
    record.send(sorcery_config.password_attribute_name).present?
  }

  sorcery_adapter.define_callback :after, :save, :clear_virtual_password, if: proc { |record|
    record.send(sorcery_config.password_attribute_name).present?
  }

  attr_accessor sorcery_config.password_attribute_name
end