Skip to content

Instantly share code, notes, and snippets.

@smichaelis
Created May 4, 2010 11:34
Show Gist options
  • Save smichaelis/389299 to your computer and use it in GitHub Desktop.
Save smichaelis/389299 to your computer and use it in GitHub Desktop.
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: github.com/carlhuda/bundler/issues/issue/83, 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: gist.github.com/312532 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)
end
# [...]
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)
end
property name, type, options
end
end
end
end
DataMapper::Model.send(:include, Devise::Models)
# Critical default settings:
disable_system_gems
disable_rubygems
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 self.property(name, type, options = {})
super(name, type, options.merge({:auto_validation => false}))
end
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."}))
end
# Validations without localised messages
def self.validates_uniqueness_of(name, options = {})
validates_is_unique(name, options)
end
def self.validates_format_of(name, options = {})
validates_format(name, options)
end
def self.validates_confirmation_of(name, options = {})
validates_is_confirmed(name, options)
end
def self.validates_length_of(name, options = {})
validates_length(name, options)
end
devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable, :confirmable
timestamps :at
end
@dostanko
Copy link

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
  ActionController::Routing::Routes.reload!
  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