Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
Steps to get Devise Authentication and CanCan Authorization running on Ruby on Rails 2.3.5 with DataMapper and Bundler on Google AppEngine

Steps to get Devise Authentication and CanCan Authorization running on Ruby on Rails 2.3.5 with DataMapper and Bundler on Google AppEngine:

  • Install Devise version 1.0.6 as a plugin into the Rails vendor directory. Installing as a Gem did not work for me, maybe due to bundler (see this Issue:, which involves patching Rails boot.rb etc.)

  • Add warden and cancan to your Gemfile

  • Configure Devise to use DataMapper as the orm in config/initializers/devise.rb

  • Setup ActionMailer as described in: in case you want confirmation of new users via email

  • Create a User model, which adds ActiveRecord-validations to the model in case the Devise validation-module will be used. If Devise validations will be used, DataMapper autovalidations should be disabled

  • If the rememberable module of Devise is used, the DataMapper-ORM (lib/devise/orm/data_mapper.rb) of Devise needs to be patched to use Time instead of DateTime. Otherwise an exception is thrown on setting the remember-cookie because of a missing .gmtime method

  • CanCan 1.1.1 runs out of the box, except for nested resources (e.g. comments belonging to posts). Patch controller_resource.rb to use DataMapper-get instead of ActiveRecord-find

# [...]
def find(id)
self.model_instance ||= base.get(id)
# [...]
module Devise
module Orm
module DataMapper
# [...]
# 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
# This automatically converts DateTime to Time
type = Time if type == DateTime
SCHEMA_OPTIONS.each do |old_key, new_key|
next unless options.key?(old_key)
options[new_key] = options.delete(old_key)
property name, type, options
DataMapper::Model.send(:include, Devise::Models)
# Critical default settings:
bundle_path '.gems/bundler_gems'
# List gems to bundle here:
gem 'rails_dm_datastore'
gem 'rails', "2.3.5"
# Needed for Devise-Plugin
gem 'warden'
# Authorisation
gem 'cancan'
# Confirmation Mail support
gem "actionmailer-javamail", :require_as => "java_mail"
class User
include DataMapper::Resource
# Turn off DataMapper auto validations. If the validation module of devise is used, this
# leads otherwise to duplicate error messages.
def, type, options = {})
super(name, type, options.merge({:auto_validation => false}))
property :id, Serial
# ActiveRecord-compatible validations, only needed in case the validation module is used
def self.validates_presence_of(name, options = {})
# Localisation of validtions messages, example
local_name = I18n.t(name, :default => name, :scope => [:activerecord, :attributes, :user], :count => 1)
validates_present(name, options.merge({:message => local_name+" must not be empty."}))
# Validations without localised messages
def self.validates_uniqueness_of(name, options = {})
validates_is_unique(name, options)
def self.validates_format_of(name, options = {})
validates_format(name, options)
def self.validates_confirmation_of(name, options = {})
validates_is_confirmed(name, options)
def self.validates_length_of(name, options = {})
validates_length(name, options)
devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable, :confirmable
timestamps :at
Copy link

dostanko commented Oct 10, 2010

great gist! thx!
I had problems with STI ( property :type, Discriminator in User model )

I've decided it by reloading routes in devise SessionsController

def create
  if resource = authenticate(resource_name)

but I don't understand the heart of problem, have you any comment for it?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment