diff --git a/CHANGELOG.rdoc b/CHANGELOG.rdoc index 5ed840a3..c0a2be23 100644 --- a/CHANGELOG.rdoc +++ b/CHANGELOG.rdoc @@ -4,10 +4,12 @@ * Rails 3 compatibility. * All controllers and views are namespaced, for example: Devise::SessionsController and "devise/sessions". * You can specify the controller in routes and have specific controllers for each role. + * Devise.orm is deprecated. This reduces the required API to hook your ORM with devise. * deprecations * Rails 3 compatible only. * Scoped views are no longer "sessions/users/new". Now use "users/sessions/new". + * Devise.orm is deprecated, just require "devise/orm/YOUR_ORM" instead. == 1.0.2 diff --git a/lib/devise.rb b/lib/devise.rb index 7e37c142..da6b7a26 100644 --- a/lib/devise.rb +++ b/lib/devise.rb @@ -21,12 +21,6 @@ module Devise autoload :Sha1, 'devise/encryptors/sha1' end - module Orm - autoload :ActiveRecord, 'devise/orm/active_record' - autoload :DataMapper, 'devise/orm/data_mapper' - autoload :MongoMapper, 'devise/orm/mongo_mapper' - end - ALL = [] # Authentication ones first @@ -105,14 +99,6 @@ module Devise mattr_accessor :mappings @@mappings = ActiveSupport::OrderedHash.new - # Stores the chosen ORM. - mattr_accessor :orm - @@orm = :active_record - - # TODO Remove - mattr_accessor :all - @@all = [] - # Tells if devise should apply the schema in ORMs where devise declaration # and schema belongs to the same class (as Datamapper and MongoMapper). mattr_accessor :apply_schema @@ -163,6 +149,12 @@ module Devise yield self end + # TODO Remove me on final release + def orm=(value) + ActiveSupport::Deprecation.warn "Devise.orm= and config.orm= are deprecated. " << + "Just load devise/orm/\#{ORM_NAME} if Devise supports your ORM" + end + # Sets warden configuration using a block that will be invoked on warden # initialization. # @@ -195,11 +187,6 @@ module Devise @warden_config.try :call, config end - # The class of the configured ORM - def orm_class - Devise::Orm.const_get(@@orm.to_s.camelize.to_sym) - end - # Generate a friendly string randomically to be used as token. def friendly_token ActiveSupport::SecureRandom.base64(15).tr('+/=', '-_ ').strip.delete("\n") diff --git a/lib/devise/models.rb b/lib/devise/models.rb index 4b0ed5cc..6b145e4d 100644 --- a/lib/devise/models.rb +++ b/lib/devise/models.rb @@ -57,15 +57,12 @@ module Devise # def devise(*modules) raise "You need to give at least one Devise module" if modules.empty? - options = modules.extract_options! + options = modules.extract_options! @devise_modules = Devise::ALL & modules.map(&:to_sym).uniq - Devise.orm_class.included_modules_hook(self) do - devise_modules.each do |m| - include Devise::Models.const_get(m.to_s.classify) - end - + devise_modules_hook! do + devise_modules.each { |m| include Devise::Models.const_get(m.to_s.classify) } options.each { |key, value| send(:"#{key}=", value) } end end @@ -76,6 +73,12 @@ module Devise @devise_modules ||= [] end + # The hook which is called inside devise. So your ORM can include devise + # compatibility stuff. + def devise_modules_hook! + yield + end + # Find an initialize a record setting an error if it can't be found. def find_or_initialize_with_error_by(attribute, value, error=:invalid) if value.present? diff --git a/lib/devise/orm/active_record.rb b/lib/devise/orm/active_record.rb index 4181b0d9..8f29630e 100644 --- a/lib/devise/orm/active_record.rb +++ b/lib/devise/orm/active_record.rb @@ -19,16 +19,13 @@ module Devise # add_index "accounts", ["reset_password_token"], :name => "reset_password_token", :unique => true # module ActiveRecord - # Required ORM hook. Just yield the given block in ActiveRecord. - def self.included_modules_hook(klass) - yield - end + module Schema + include Devise::Schema - include Devise::Schema - - # Tell how to apply schema methods. - def apply_schema(name, type, options={}) - column name, type.to_s.downcase.to_sym, options + # Tell how to apply schema methods. + def apply_schema(name, type, options={}) + column name, type.to_s.downcase.to_sym, options + end end end end @@ -36,6 +33,6 @@ end if defined?(ActiveRecord) ActiveRecord::Base.extend Devise::Models - ActiveRecord::ConnectionAdapters::Table.send :include, Devise::Orm::ActiveRecord - ActiveRecord::ConnectionAdapters::TableDefinition.send :include, Devise::Orm::ActiveRecord + ActiveRecord::ConnectionAdapters::Table.send :include, Devise::Orm::ActiveRecord::Schema + ActiveRecord::ConnectionAdapters::TableDefinition.send :include, Devise::Orm::ActiveRecord::Schema end \ No newline at end of file diff --git a/lib/devise/orm/data_mapper.rb b/lib/devise/orm/data_mapper.rb index 8a3a1a75..f258634a 100644 --- a/lib/devise/orm/data_mapper.rb +++ b/lib/devise/orm/data_mapper.rb @@ -1,83 +1,89 @@ module Devise module Orm module DataMapper - module InstanceMethods - def save(flag=nil) - if flag == false + module Hook + def devise_modules_hook! + extend Schema + include Compatibility + yield + return unless Devise.apply_schema + devise_modules.each { |m| send(m) if respond_to?(m, true) } + end + end + + module Schema + include Devise::Schema + + SCHEMA_OPTIONS = { + :null => :nullable, + :limit => :length + } + + # Tell how to apply schema methods. This automatically maps :limit to + # :length and :null to :nullable. + def apply_schema(name, type, options={}) + SCHEMA_OPTIONS.each do |old_key, new_key| + next unless options.key?(old_key) + options[new_key] = options.delete(old_key) + end + + property name, type, options + end + end + + module Compatibility + extend ActiveSupport::Concern + + module ClassMethods + # Hooks for confirmable + def before_create(*args) + wrap_hook(:before, *args) + end + + def after_create(*args) + wrap_hook(:after, *args) + end + + def wrap_hook(action, *args) + options = args.extract_options! + + args.each do |callback| + send action, :create, callback + class_eval <<-METHOD, __FILE__, __LINE__ + 1 + def #{callback} + super if #{options[:if] || true} + end + METHOD + end + end + + # Add ActiveRecord like finder + def find(*args) + options = args.extract_options! + case args.first + when :first + first(options) + when :all + all(options) + else + get(*args) + end + end + end + + def save(options=nil) + if options.is_a?(Hash) && options[:validate] == false save! else super() end end end - - def self.included_modules_hook(klass) - klass.send :extend, self - klass.send :include, InstanceMethods - - yield - - klass.devise_modules.each do |mod| - klass.send(mod) if klass.respond_to?(mod) - end - end - - include Devise::Schema - - SCHEMA_OPTIONS = { - :null => :nullable, - :limit => :length - } - - # Hooks for confirmable - def before_create(*args) - wrap_hook(:before, *args) - end - - def after_create(*args) - wrap_hook(:after, *args) - end - - def wrap_hook(action, *args) - options = args.extract_options! - - args.each do |callback| - send action, :create, callback - class_eval <<-METHOD, __FILE__, __LINE__ + 1 - def #{callback} - super if #{options[:if] || true} - end - METHOD - end - end - - # Add ActiveRecord like finder - def find(*args) - options = args.extract_options! - case args.first - when :first - first(options) - when :all - all(options) - else - get(*args) - end - end - - # Tell how to apply schema methods. This automatically maps :limit to - # :length and :null to :nullable. - def apply_schema(name, type, options={}) - return unless Devise.apply_schema - - SCHEMA_OPTIONS.each do |old_key, new_key| - next unless options.key?(old_key) - options[new_key] = options.delete(old_key) - end - - property name, type, options - end end end end -DataMapper::Model.send(:include, Devise::Models) +DataMapper::Model.class_eval do + extend Devise::ORM::DataMapper::Hook + include Devise::Models +end \ No newline at end of file diff --git a/lib/devise/orm/mongo_mapper.rb b/lib/devise/orm/mongo_mapper.rb index 25b524f8..269c4f08 100644 --- a/lib/devise/orm/mongo_mapper.rb +++ b/lib/devise/orm/mongo_mapper.rb @@ -1,39 +1,51 @@ module Devise module Orm module MongoMapper - def self.included_modules_hook(klass) - klass.send :extend, self - yield - - klass.devise_modules.each do |mod| - klass.send(mod) if klass.respond_to?(mod) + module Hook + def devise_modules_hook! + extend Schema + include Compatibility + yield + return unless Devise.apply_schema + devise_modules.each { |m| send(m) if respond_to?(m, true) } end end - - def find(*args) - options = args.extract_options! - case args.first - when :first - first(options) - when :all - all(options) - else - super + + module Schema + include Devise::Schema + + # Tell how to apply schema methods. This automatically converts DateTime + # to Time, since MongoMapper does not recognize the former. + def apply_schema(name, type, options={}) + type = Time if type == DateTime + key name, type, options end end - - include Devise::Schema - # Tell how to apply schema methods. This automatically converts DateTime - # to Time, since MongoMapper does not recognize the former. - def apply_schema(name, type, options={}) - return unless Devise.apply_schema - type = Time if type == DateTime - key name, type, options + module Compatibility + extend ActiveSupport::Concern + + module ClassMethods + def find(*args) + options = args.extract_options! + case args.first + when :first + first(options) + when :all + all(options) + else + super + end + end + end end end end end -MongoMapper::Document::ClassMethods.send(:include, Devise::Models) -MongoMapper::EmbeddedDocument::ClassMethods.send(:include, Devise::Models) +[MongoMapper::Document, MongoMapper::EmbeddedDocument].each do |mod| + mod::ClassMethods.class_eval do + include Devise::Models + include Devise::Orm::MongoMapper::Hook + end +end \ No newline at end of file diff --git a/lib/devise/rails.rb b/lib/devise/rails.rb index 8ea2a847..10178e35 100644 --- a/lib/devise/rails.rb +++ b/lib/devise/rails.rb @@ -8,9 +8,5 @@ module Devise config.middleware.use Warden::Manager do |config| Devise.configure_warden(config) end - - initializer "devise.load_orm" do - require "devise/orm/#{Devise.orm}" - end end end \ No newline at end of file diff --git a/test/rails_app/config/initializers/devise.rb b/test/rails_app/config/initializers/devise.rb index 34416332..f0f5b962 100644 --- a/test/rails_app/config/initializers/devise.rb +++ b/test/rails_app/config/initializers/devise.rb @@ -38,7 +38,6 @@ Devise.setup do |config| # Load and configure the ORM. Supports :active_record, :data_mapper and :mongo_mapper. require "devise/orm/#{DEVISE_ORM}" - config.orm = DEVISE_ORM # Turn scoped views on. Before rendering "sessions/new", it will first check for # "sessions/users/new". It's turned off by default because it's slower if you