From fddf95fe0ae4b8cde4b343465f88b0a6b56ba984 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Sun, 22 Nov 2009 09:14:58 -0200 Subject: [PATCH] More improvements in DataMapper support front. --- CHANGELOG.rdoc | 1 + generators/devise_install/templates/devise.rb | 2 +- lib/devise/models/authenticatable.rb | 11 ++-- lib/devise/orm/data_mapper.rb | 62 +++++++++++++++++++ lib/devise/orm/mongo_mapper.rb | 1 - lib/devise/schema.rb | 2 +- 6 files changed, 70 insertions(+), 9 deletions(-) create mode 100644 lib/devise/orm/data_mapper.rb diff --git a/CHANGELOG.rdoc b/CHANGELOG.rdoc index 618c69c7ea..2619e15d92 100644 --- a/CHANGELOG.rdoc +++ b/CHANGELOG.rdoc @@ -1,4 +1,5 @@ * enhancements + * Added DataMapper support * Remove store_location from authenticatable strategy and add it to failure app * Allow a strategy to be placed after authenticatable * [#45] Do not rely attribute? methods, since they are not added on Datamapper diff --git a/generators/devise_install/templates/devise.rb b/generators/devise_install/templates/devise.rb index 2aaf07c826..07c5d61312 100644 --- a/generators/devise_install/templates/devise.rb +++ b/generators/devise_install/templates/devise.rb @@ -37,7 +37,7 @@ # Configure the e-mail address which will be shown in DeviseMailer. # config.mailer_sender = "foo.bar@yourapp.com" - # Configure the ORM. Supports :active_record and :mongo_mapper + # Configure the ORM. Supports :active_record, :data_mapper and :mongo_mapper. # config.orm = :active_record # Turn scoped views on. Before rendering "sessions/new", it will first check for diff --git a/lib/devise/models/authenticatable.rb b/lib/devise/models/authenticatable.rb index 82281bbd52..8c0dec2f48 100644 --- a/lib/devise/models/authenticatable.rb +++ b/lib/devise/models/authenticatable.rb @@ -87,11 +87,10 @@ def find_for_authentication(conditions) # Attempt to find a user by it's email. If not user is found, returns a # new user with an email not found error. def find_or_initialize_with_error_by_email(email) - perishable = find_or_initialize_by_email(email) - if perishable.new_record? - perishable.errors.add(:email, :not_found, :default => 'not found') - end - perishable + attributes = { :email => email } + record = find(:first, :conditions => attributes) || new(attributes) + record.errors.add(:email, :not_found, :default => 'not found') if record.new_record? + record end # Hook to serialize user into session. Overwrite if you want. @@ -103,7 +102,7 @@ def serialize_into_session(record) def serialize_from_session(keys) klass, id = keys raise "#{self} cannot serialize from #{klass} session since it's not its ancestors" unless klass <= self - klass.find_by_id(id) + klass.find(:first, :conditions => { :id => id }) end end diff --git a/lib/devise/orm/data_mapper.rb b/lib/devise/orm/data_mapper.rb new file mode 100644 index 0000000000..e033464fda --- /dev/null +++ b/lib/devise/orm/data_mapper.rb @@ -0,0 +1,62 @@ +module Devise + module Orm + module DataMapper + def self.included_modules_hook(klass, modules) + klass.send :extend, self + + # DataMapper validations have a completely different API + if modules.include?(:validatable) && !klass.respond_to?(:validates_presence_of) + raise ":validatable is not supported in DataMapper, please craft your validations by hand" + end + + modules.each do |mod| + klass.send(mod) + end + end + + include Devise::Schema + + SCHEMA_OPTIONS = { + :null => :nullable, + :limit => :length + } + + # Hooks for confirmable + def before_create(*args) + before :create, *args + end + + def after_create(*args) + after :create, *args + end + + # Add ActiveRecord like finder + def find(*args) + options = args.extract_options! + case args.first + when :first + first(options.merge(options.delete(:conditions))) + when :all + all(options.merge(options.delete(:conditions))) + 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[old_key] + options[new_key] = options.delete(old_key) + end + + property name, type, options + end + end + end +end + +DataMapper::Model.send(:include, Devise::Models) diff --git a/lib/devise/orm/mongo_mapper.rb b/lib/devise/orm/mongo_mapper.rb index 6adb721f32..626e865623 100644 --- a/lib/devise/orm/mongo_mapper.rb +++ b/lib/devise/orm/mongo_mapper.rb @@ -1,7 +1,6 @@ module Devise module Orm module MongoMapper - # Include attributes modules and set the proper ones. def self.included_modules_hook(klass, modules) klass.send :extend, self diff --git a/lib/devise/schema.rb b/lib/devise/schema.rb index 880b1240e8..7a0e19bd88 100644 --- a/lib/devise/schema.rb +++ b/lib/devise/schema.rb @@ -42,7 +42,7 @@ def rememberable end # Overwrite with specific modification to create your own schema. - def apply_schema(name, tupe, options={}) + def apply_schema(name, type, options={}) raise NotImplementedError end end