tpitale-dm-rails 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. data/.document +5 -0
  2. data/Gemfile +63 -0
  3. data/LICENSE +20 -0
  4. data/README.rdoc +595 -0
  5. data/Rakefile +27 -0
  6. data/VERSION +1 -0
  7. data/dm-rails.gemspec +94 -0
  8. data/lib/dm-rails/configuration.rb +76 -0
  9. data/lib/dm-rails/mass_assignment_security.rb +89 -0
  10. data/lib/dm-rails/middleware/identity_map.rb +20 -0
  11. data/lib/dm-rails/multiparameter_attributes.rb +167 -0
  12. data/lib/dm-rails/railtie.rb +100 -0
  13. data/lib/dm-rails/railties/controller_runtime.rb +45 -0
  14. data/lib/dm-rails/railties/database.rake +106 -0
  15. data/lib/dm-rails/railties/i18n_support.rb +12 -0
  16. data/lib/dm-rails/railties/log_listener.rb +39 -0
  17. data/lib/dm-rails/railties/log_subscriber.rb +54 -0
  18. data/lib/dm-rails/session_store.rb +77 -0
  19. data/lib/dm-rails/setup.rb +84 -0
  20. data/lib/dm-rails/storage.rb +209 -0
  21. data/lib/dm-rails.rb +1 -0
  22. data/lib/generators/data_mapper/migration/migration_generator.rb +30 -0
  23. data/lib/generators/data_mapper/migration/templates/migration.rb +23 -0
  24. data/lib/generators/data_mapper/model/model_generator.rb +23 -0
  25. data/lib/generators/data_mapper/model/templates/model.rb +11 -0
  26. data/lib/generators/data_mapper/observer/observer_generator.rb +19 -0
  27. data/lib/generators/data_mapper/observer/templates/observer.rb +7 -0
  28. data/lib/generators/data_mapper.rb +82 -0
  29. data/spec/models/fake.rb +31 -0
  30. data/spec/models/topic.rb +11 -0
  31. data/spec/spec.opts +3 -0
  32. data/spec/spec_helper.rb +19 -0
  33. data/spec/unit/mass_assignment_security_spec.rb +43 -0
  34. data/spec/unit/multiparameter_attributes_spec.rb +168 -0
  35. data/tasks/clean.rake +6 -0
  36. data/tasks/yard.rake +9 -0
  37. data/tasks/yardstick.rake +20 -0
  38. metadata +161 -0
data/Rakefile ADDED
@@ -0,0 +1,27 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ gem 'jeweler', '~> 1.6.4'
6
+ require 'jeweler'
7
+
8
+ Jeweler::Tasks.new do |gem|
9
+ gem.name = 'dm-rails'
10
+ gem.summary = 'Use DataMapper with Rails 3'
11
+ gem.description = 'Integrate DataMapper with Rails 3'
12
+ gem.email = 'gamsnjaga@gmail.com'
13
+ gem.homepage = 'http://github.com/datamapper/%s' % gem.name
14
+ gem.authors = [ 'Martin Gamsjaeger (snusnu)', 'Dan Kubb' ]
15
+
16
+ gem.rubyforge_project = 'datamapper'
17
+ end
18
+
19
+ Jeweler::GemcutterTasks.new
20
+
21
+ FileList['tasks/**/*.rake'].each { |task| import task }
22
+ rescue LoadError
23
+ puts 'Jeweler (or a dependency) not available. Install it with: gem install jeweler'
24
+ end
25
+
26
+ require "spec/rake/spectask"
27
+ Spec::Rake::SpecTask.new
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 1.2.1
data/dm-rails.gemspec ADDED
@@ -0,0 +1,94 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "tpitale-dm-rails"
8
+ s.version = "1.2.1"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Martin Gamsjaeger (snusnu)", "Dan Kubb"]
12
+ s.date = "2011-10-09"
13
+ s.description = "Integrate DataMapper with Rails 3"
14
+ s.email = "gamsnjaga@gmail.com"
15
+ s.extra_rdoc_files = [
16
+ "LICENSE",
17
+ "README.rdoc"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ "Gemfile",
22
+ "LICENSE",
23
+ "README.rdoc",
24
+ "Rakefile",
25
+ "VERSION",
26
+ "dm-rails.gemspec",
27
+ "lib/dm-rails.rb",
28
+ "lib/dm-rails/configuration.rb",
29
+ "lib/dm-rails/mass_assignment_security.rb",
30
+ "lib/dm-rails/middleware/identity_map.rb",
31
+ "lib/dm-rails/multiparameter_attributes.rb",
32
+ "lib/dm-rails/railtie.rb",
33
+ "lib/dm-rails/railties/controller_runtime.rb",
34
+ "lib/dm-rails/railties/database.rake",
35
+ "lib/dm-rails/railties/i18n_support.rb",
36
+ "lib/dm-rails/railties/log_listener.rb",
37
+ "lib/dm-rails/railties/log_subscriber.rb",
38
+ "lib/dm-rails/session_store.rb",
39
+ "lib/dm-rails/setup.rb",
40
+ "lib/dm-rails/storage.rb",
41
+ "lib/generators/data_mapper.rb",
42
+ "lib/generators/data_mapper/migration/migration_generator.rb",
43
+ "lib/generators/data_mapper/migration/templates/migration.rb",
44
+ "lib/generators/data_mapper/model/model_generator.rb",
45
+ "lib/generators/data_mapper/model/templates/model.rb",
46
+ "lib/generators/data_mapper/observer/observer_generator.rb",
47
+ "lib/generators/data_mapper/observer/templates/observer.rb",
48
+ "spec/models/fake.rb",
49
+ "spec/models/topic.rb",
50
+ "spec/spec.opts",
51
+ "spec/spec_helper.rb",
52
+ "spec/unit/mass_assignment_security_spec.rb",
53
+ "spec/unit/multiparameter_attributes_spec.rb",
54
+ "tasks/clean.rake",
55
+ "tasks/yard.rake",
56
+ "tasks/yardstick.rake"
57
+ ]
58
+ s.homepage = "http://github.com/datamapper/dm-rails"
59
+ s.require_paths = ["lib"]
60
+ s.rubyforge_project = "datamapper"
61
+ s.rubygems_version = "1.8.11"
62
+ s.summary = "Use DataMapper with Rails 3"
63
+
64
+ if s.respond_to? :specification_version then
65
+ s.specification_version = 3
66
+
67
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
68
+ s.add_runtime_dependency(%q<dm-core>, ["~> 1.2.0"])
69
+ s.add_runtime_dependency(%q<dm-active_model>, ["~> 1.2.0"])
70
+ s.add_runtime_dependency(%q<actionpack>, ["~> 3.1.0"])
71
+ s.add_runtime_dependency(%q<railties>, ["~> 3.1.0"])
72
+ s.add_development_dependency(%q<jeweler>, ["~> 1.6.4"])
73
+ s.add_development_dependency(%q<rake>, ["~> 0.9.2"])
74
+ s.add_development_dependency(%q<rspec>, ["~> 1.3.2"])
75
+ else
76
+ s.add_dependency(%q<dm-core>, ["~> 1.2.0"])
77
+ s.add_dependency(%q<dm-active_model>, ["~> 1.2.0"])
78
+ s.add_dependency(%q<actionpack>, ["~> 3.1.0"])
79
+ s.add_dependency(%q<railties>, ["~> 3.1.0"])
80
+ s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
81
+ s.add_dependency(%q<rake>, ["~> 0.9.2"])
82
+ s.add_dependency(%q<rspec>, ["~> 1.3.2"])
83
+ end
84
+ else
85
+ s.add_dependency(%q<dm-core>, ["~> 1.2.0"])
86
+ s.add_dependency(%q<dm-active_model>, ["~> 1.2.0"])
87
+ s.add_dependency(%q<actionpack>, ["~> 3.1.0"])
88
+ s.add_dependency(%q<railties>, ["~> 3.1.0"])
89
+ s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
90
+ s.add_dependency(%q<rake>, ["~> 0.9.2"])
91
+ s.add_dependency(%q<rspec>, ["~> 1.3.2"])
92
+ end
93
+ end
94
+
@@ -0,0 +1,76 @@
1
+ require 'active_support/core_ext/hash/except'
2
+ require 'active_support/core_ext/class/attribute_accessors'
3
+
4
+ module Rails
5
+ module DataMapper
6
+
7
+ mattr_accessor :configuration
8
+
9
+ class Configuration
10
+
11
+ attr_accessor :raw
12
+ attr_accessor :root
13
+
14
+ def self.create
15
+ Rails::DataMapper.configuration ||= new
16
+ end
17
+
18
+ def environments
19
+ raw.keys
20
+ end
21
+
22
+ def repositories
23
+ @repositories ||= raw.reject { |k,v| k =~ /defaults/ }.inject({}) do |repositories, pair|
24
+ environment, config = pair.first, pair.last
25
+ repositories[environment] = begin
26
+ c = config['repositories'] || {}
27
+ c['default'] = config.except('repositories') if config.except('repositories')
28
+ normalize_repository_config(c)
29
+ end
30
+ repositories
31
+ end
32
+ end
33
+
34
+ def resource_naming_convention
35
+ @resource_naming_convention ||= {}
36
+ end
37
+
38
+ def field_naming_convention
39
+ @field_naming_convention ||= {}
40
+ end
41
+
42
+ private
43
+
44
+ def normalize_repository_config(hash)
45
+ config = {}
46
+ hash.each do |key, value|
47
+
48
+ config[key] = if value.kind_of?(Hash)
49
+ normalize_repository_config(value)
50
+ elsif key == 'port'
51
+ value.to_i
52
+ elsif key == 'adapter' && value == 'postgresql'
53
+ 'postgres'
54
+ elsif (key == 'database' || key == 'path') && hash['adapter'] =~ /sqlite/
55
+ value == ':memory:' ? value : File.expand_path(hash[key], root)
56
+ else
57
+ value
58
+ end
59
+
60
+ # FIXME Rely on a new dm-sqlite-adapter to do the right thing
61
+ # For now, we need to make sure that both 'path' and 'database'
62
+ # point to the same thing, since dm-sqlite-adapter always passes
63
+ # both to the underlying do_sqlite3 adapter and there's no
64
+ # guarantee which one will be used
65
+
66
+ config['path'] = config[key] if key == 'database'
67
+ config['database'] = config[key] if key == 'path'
68
+
69
+ end
70
+ config
71
+ end
72
+
73
+ end
74
+
75
+ end
76
+ end
@@ -0,0 +1,89 @@
1
+ require 'dm-core'
2
+ require 'active_support/core_ext/class/attribute'
3
+ require 'active_support/concern'
4
+ require 'active_model'
5
+
6
+ module ActiveModel
7
+ module MassAssignmentSecurity
8
+ # Provides a patched version of the Sanitizer used in Rails to handle property
9
+ # and relationship objects as keys. There is no way to inject a custom sanitizer
10
+ # without reimplementing the permission sets.
11
+ module Sanitizer
12
+ # Returns all attributes not denied by the authorizer.
13
+ #
14
+ # @param [Hash{Symbol,String,::DataMapper::Property,::DataMapper::Relationship=>Object}] attributes
15
+ # Names and values of attributes to sanitize.
16
+ # @return [Hash]
17
+ # Sanitized hash of attributes.
18
+ def sanitize(attributes)
19
+ sanitized_attributes = attributes.reject do |key, value|
20
+ key_name = key.name rescue key
21
+ deny?(key_name)
22
+ end
23
+ debug_protected_attribute_removal(attributes, sanitized_attributes)
24
+ sanitized_attributes
25
+ end
26
+ end
27
+ end
28
+ end
29
+
30
+ module DataMapper
31
+ # Include this module into a DataMapper model to enable ActiveModel's mass
32
+ # assignment security.
33
+ #
34
+ # To use second parameter of {#attributes=} make sure to include this module
35
+ # last.
36
+ module MassAssignmentSecurity
37
+ extend ::ActiveSupport::Concern
38
+ include ::ActiveModel::MassAssignmentSecurity
39
+
40
+ module ClassMethods
41
+ extend ::ActiveModel::MassAssignmentSecurity::ClassMethods
42
+
43
+ def logger
44
+ @logger ||= ::DataMapper.logger
45
+ end
46
+ end
47
+
48
+ # Sanitizes the specified +attributes+ according to the defined mass-assignment
49
+ # security rules and calls +super+ with the result.
50
+ #
51
+ # Use either +attr_accessible+ to specify which attributes are allowed to be
52
+ # assigned via {#attributes=}, or +attr_protected+ to specify which attributes
53
+ # are *not* allowed to be assigned via {#attributes=}.
54
+ #
55
+ # +attr_accessible+ and +attr_protected+ are mutually exclusive.
56
+ #
57
+ # @param [Hash{Symbol,String,::DataMapper::Property,::DataMapper::Relationship=>Object}] attributes
58
+ # Names and values of attributes to sanitize.
59
+ # @param [Boolean] guard_protected_attributes
60
+ # Determines whether mass-security rules are applied (when +true+) or not.
61
+ # @return [Hash]
62
+ # Sanitized hash of attributes.
63
+ # @api public
64
+ #
65
+ # @example [Usage]
66
+ # class User
67
+ # include DataMapper::Resource
68
+ # include DataMapper::MassAssignmentSecurity
69
+ #
70
+ # property :name, String
71
+ # property :is_admin, Boolean
72
+ #
73
+ # # Only allow name to be set via #attributes=
74
+ # attr_accessible :name
75
+ # end
76
+ #
77
+ # user = User.new
78
+ # user.attributes = { :username => 'Phusion', :is_admin => true }
79
+ # user.username # => "Phusion"
80
+ # user.is_admin # => false
81
+ #
82
+ # user.send(:attributes=, { :username => 'Phusion', :is_admin => true }, false)
83
+ # user.is_admin # => true
84
+ def attributes=(attributes, guard_protected_attributes = true)
85
+ attributes = sanitize_for_mass_assignment(attributes) if guard_protected_attributes
86
+ super(attributes)
87
+ end
88
+ end
89
+ end
@@ -0,0 +1,20 @@
1
+ module Rails
2
+ module DataMapper
3
+ module Middleware
4
+
5
+ class IdentityMap
6
+ def initialize(app, name = :default)
7
+ @app = app
8
+ @name = name.to_sym
9
+ end
10
+
11
+ def call(env)
12
+ ::DataMapper.repository(@name) do
13
+ @app.call(env)
14
+ end
15
+ end
16
+ end
17
+
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,167 @@
1
+ require 'active_support/core_ext/module/aliasing'
2
+
3
+ module Rails
4
+ module DataMapper
5
+ # Encapsulates an error of a multiparameter assignment.
6
+ class MultiparameterAssignmentError < StandardError
7
+ # Gets the target attribute of the assignment.
8
+ # @return [String]
9
+ attr_reader :attribute
10
+
11
+ # Gets the assigned values.
12
+ # @return [Array]
13
+ attr_reader :values
14
+
15
+ # Gets the exception raised on the assignment.
16
+ # @return [Exception]
17
+ attr_reader :exception
18
+
19
+ # Initializes a new instance of the {MultiparameterAssignmentError} class.
20
+ #
21
+ # @param [String] attribute The target attribute of the assignment.
22
+ # @param [Array] values The assigned values.
23
+ # @param [Exception] exception The exception raised on the assignment.
24
+ def initialize(attribute, values, exception)
25
+ super("Could not assign #{values.inspect} to #{attribute} (#{exception.message}).")
26
+ @attribute = attribute
27
+ @values = values
28
+ @exception = exception
29
+ end
30
+ end
31
+
32
+ # Raised by {MultiparameterAttributes#attributes=} when there are errors when
33
+ # merging multiparameter attributes. Use {#errors} to get the array of errors
34
+ # occured.
35
+ class MultiparameterAssignmentErrors < StandardError
36
+ # Gets the array of assignment errors.
37
+ # @return [Array<MultiparameterAssignmentError>]
38
+ attr_reader :errors
39
+
40
+ # Initializes a new instance of the {MultiparameterAssignmentErrors} class.
41
+ #
42
+ # @param [Array<MultiparameterAssignmentError>] errors
43
+ # The array of assignment errors.
44
+ # @param [String] message Optional error message.
45
+ def initialize(errors, message = nil)
46
+ super(message || "#{errors.size} error#{errors.size == 1 ? '' : 's'} on assignment of multiparameter attributes.")
47
+ @errors = errors
48
+ end
49
+ end
50
+
51
+ # Include this module into a DataMapper model to enable multiparameter
52
+ # attributes.
53
+ #
54
+ # A multiparameter attribute has +attr(Xc)+ as name where +attr+ specifies
55
+ # the attribute, +X+ the position of the value, and +c+ an optional typecast
56
+ # identifier. All values that share an +attr+ are sorted by their position,
57
+ # optionally cast using +#to_c+ (where +c+ is the typecast identifier) and
58
+ # then used to instantiate the proper attribute value.
59
+ #
60
+ # @example
61
+ # # Assigning a hash with multiparameter values for a +Date+ property called
62
+ # # +written_on+:
63
+ # resource.attributes = {
64
+ # 'written_on(1i)' => '2004',
65
+ # 'written_on(2i)' => '6',
66
+ # 'written_on(3i)' => '24' }
67
+ #
68
+ # # +Date+ will be initialized with each string cast to a number using
69
+ # # #to_i.
70
+ # resource.written_on == Date.new(2004, 6, 24)
71
+ module MultiparameterAttributes
72
+ # Merges multiparameter attributes and calls +super+ with the merged
73
+ # attributes.
74
+ #
75
+ # @param [Hash{String,Symbol=>Object}] attributes
76
+ # Names and values of attributes to assign.
77
+ # @return [Hash]
78
+ # Names and values of attributes assigned.
79
+ # @raise [MultiparameterAssignmentErrors]
80
+ # One or more multiparameters could not be assigned.
81
+ # @api public
82
+ def attributes=(attributes)
83
+ attribs = attributes.dup
84
+ multi_parameter_attributes = []
85
+ attribs.each do |k, v|
86
+ if k.to_s.include?("(")
87
+ multi_parameter_attributes << [ k, v ]
88
+ attribs.delete(k)
89
+ end
90
+ end
91
+
92
+ attribs.merge!(merge_multiparameter_attributes(multi_parameter_attributes))
93
+ super(attribs)
94
+ end
95
+
96
+ protected
97
+ def merge_multiparameter_attributes(pairs)
98
+ pairs = extract_multiparameter_attributes(pairs)
99
+
100
+ errors = []
101
+ attributes = {}
102
+ pairs.each do |name, values_with_empty_parameters|
103
+ # ActiveRecord keeps the empty values to set dates without a year.
104
+ # Removing all nils (instead of removing only trailing nils) seems
105
+ # like a weird behavior though.
106
+ values = values_with_empty_parameters.compact
107
+
108
+ if values.empty?
109
+ attributes[name] = nil
110
+ next
111
+ end
112
+
113
+ klass = properties[name].dump_class
114
+ begin
115
+ attributes[name] =
116
+ if klass == Time
117
+ Time.local(*values)
118
+ elsif klass == Date
119
+ # Date does not replace nil values with defaults.
120
+ Date.new(*values_with_empty_parameters.map { |v| v.nil? ? 1 : v })
121
+ else
122
+ klass.new(*values)
123
+ end
124
+ rescue => ex
125
+ errors << MultiparameterAssignmentError.new(name, values, ex)
126
+ end
127
+ end
128
+
129
+ unless errors.empty?
130
+ raise MultiparameterAssignmentErrors.new(errors)
131
+ end
132
+
133
+ attributes
134
+ end
135
+
136
+ def extract_multiparameter_attributes(pairs)
137
+ attributes = {}
138
+
139
+ for multiparameter_name, value in pairs
140
+ unless multiparameter_name =~ /\A ([^\)]+) \( ([0-9]+) ([a-z])? \) \z/x
141
+ raise "Invalid multiparameter name #{multiparameter_name.inspect}."
142
+ end
143
+
144
+ name, position, typecast = $1, $2, $3
145
+ attributes[name] ||= []
146
+
147
+ parameter_value =
148
+ if value.empty?
149
+ nil
150
+ elsif typecast
151
+ value.send('to_' + typecast)
152
+ else
153
+ value
154
+ end
155
+
156
+ attributes[name] << [ position, parameter_value ]
157
+ end
158
+
159
+ # Order each parameter array according to the position, then discard the
160
+ # position.
161
+ attributes.each { |name, values|
162
+ attributes[name] = values.sort_by{ |v| v.first }.collect { |v| v.last }
163
+ }
164
+ end
165
+ end # MultiparameterAttributes
166
+ end
167
+ end
@@ -0,0 +1,100 @@
1
+ require 'dm-core'
2
+ require 'dm-active_model'
3
+
4
+ require 'rails'
5
+ require 'active_model/railtie'
6
+
7
+ # Comment taken from active_record/railtie.rb
8
+ #
9
+ # For now, action_controller must always be present with
10
+ # rails, so let's make sure that it gets required before
11
+ # here. This is needed for correctly setting up the middleware.
12
+ # In the future, this might become an optional require.
13
+ require 'action_controller/railtie'
14
+
15
+ require 'dm-rails/setup'
16
+ require "dm-rails/railties/log_subscriber"
17
+ require "dm-rails/railties/i18n_support"
18
+
19
+ # The module provided in there is made available
20
+ # but users will still need to include it into the
21
+ # models they want it to use it in.
22
+ require 'dm-rails/mass_assignment_security'
23
+ require 'dm-rails/multiparameter_attributes'
24
+
25
+ module Rails
26
+ module DataMapper
27
+
28
+ class Railtie < Rails::Railtie
29
+
30
+ config.data_mapper = Rails::DataMapper::Configuration.create
31
+
32
+ config.app_generators.orm :data_mapper, :migration => true
33
+
34
+
35
+ # Support overwriting crucial steps in subclasses
36
+
37
+ def configure_data_mapper(app)
38
+ app.config.data_mapper.root = Rails.root
39
+ app.config.data_mapper.raw = app.config.database_configuration
40
+ end
41
+
42
+ def setup_i18n_support(app)
43
+ ::DataMapper::Model.append_extensions(::ActiveModel::Translation)
44
+ ::DataMapper::Model.append_extensions(Rails::DataMapper::I18nSupport)
45
+ end
46
+
47
+ def setup_controller_runtime(app)
48
+ require "dm-rails/railties/controller_runtime"
49
+ ActiveSupport.on_load(:action_controller) do
50
+ include Rails::DataMapper::Railties::ControllerRuntime
51
+ end
52
+ end
53
+
54
+ def setup_logger(app, logger)
55
+ Rails::DataMapper.setup_logger(logger)
56
+ end
57
+
58
+
59
+ initializer 'data_mapper.configuration' do |app|
60
+ configure_data_mapper(app)
61
+ ::DataMapper::Model.append_inclusions(Rails::DataMapper::MultiparameterAttributes)
62
+ end
63
+
64
+ initializer 'data_mapper.logger' do |app|
65
+ setup_logger(app, Rails.logger)
66
+ end
67
+
68
+ initializer 'data_mapper.i18n_support' do |app|
69
+ setup_i18n_support(app)
70
+ end
71
+
72
+ # Expose database runtime to controller for logging.
73
+ initializer "data_mapper.log_runtime" do |app|
74
+ setup_controller_runtime(app)
75
+ end
76
+
77
+ # Preload all models once in production mode,
78
+ # and before every request in development mode
79
+ initializer "datamapper.add_to_prepare" do |app|
80
+ config.to_prepare { Rails::DataMapper.preload_models(app) }
81
+ end
82
+
83
+ # Run setup code once in after_initialize to make sure all initializers
84
+ # are in effect once we setup the connection. Also, this will make sure
85
+ # that the connection gets set up after all models have been loaded,
86
+ # because #after_initialize is guaranteed to run after #to_prepare.
87
+ # Both production and development environment will execute the setup
88
+ # code only once.
89
+ config.after_initialize do |app|
90
+ Rails::DataMapper.setup(Rails.env)
91
+ end
92
+
93
+ rake_tasks do
94
+ load 'dm-rails/railties/database.rake'
95
+ end
96
+
97
+ end
98
+
99
+ end
100
+ end
@@ -0,0 +1,45 @@
1
+ require 'active_support/core_ext/module/attr_internal'
2
+
3
+ module Rails
4
+ module DataMapper
5
+ module Railties
6
+
7
+ module ControllerRuntime
8
+
9
+ extend ActiveSupport::Concern
10
+
11
+ protected
12
+
13
+ attr_internal :db_runtime
14
+
15
+ def cleanup_view_runtime
16
+ # TODO add checks if DataMapper is connected to a repository.
17
+ # If it is, do this, if it isn't, just delegate to super
18
+ db_rt_before_render = ::DataMapper::Railties::LogSubscriber.reset_runtime
19
+ runtime = super
20
+ db_rt_after_render = ::DataMapper::Railties::LogSubscriber.reset_runtime
21
+ self.db_runtime = db_rt_before_render + db_rt_after_render
22
+ runtime - db_rt_after_render
23
+ end
24
+
25
+ def append_info_to_payload(payload)
26
+ super
27
+ payload[:db_runtime] = db_runtime
28
+ end
29
+
30
+
31
+ module ClassMethods
32
+
33
+ def log_process_action(payload)
34
+ messages, db_runtime = super, payload[:db_runtime]
35
+ messages << ("Models: %.3fms" % db_runtime.to_f) if db_runtime
36
+ messages
37
+ end
38
+
39
+ end
40
+
41
+ end
42
+
43
+ end
44
+ end
45
+ end