ardm 0.2.7 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. data/Gemfile +5 -2
  2. data/README.md +45 -39
  3. data/lib/ardm/{active_record → ar}/associations.rb +32 -14
  4. data/lib/ardm/ar/base.rb +53 -0
  5. data/lib/ardm/{active_record → ar}/collection.rb +0 -0
  6. data/lib/ardm/ar/data_mapper_constant.rb +1 -0
  7. data/lib/ardm/{active_record → ar}/data_mapper_constant_proxy.rb +1 -1
  8. data/lib/ardm/{active_record → ar}/dirty.rb +1 -1
  9. data/lib/ardm/ar/finalize.rb +26 -0
  10. data/lib/ardm/{active_record → ar}/hooks.rb +1 -1
  11. data/lib/ardm/{active_record → ar}/inheritance.rb +1 -1
  12. data/lib/ardm/{active_record → ar}/is/state_machine.rb +1 -1
  13. data/lib/ardm/{active_record → ar}/is.rb +3 -3
  14. data/lib/ardm/{active_record → ar}/persistence.rb +1 -1
  15. data/lib/ardm/{active_record → ar}/predicate_builder/array_handler.rb +1 -1
  16. data/lib/ardm/{active_record → ar}/predicate_builder/rails3.rb +1 -1
  17. data/lib/ardm/{active_record → ar}/predicate_builder/rails4.rb +1 -1
  18. data/lib/ardm/{active_record → ar}/predicate_builder/relation_handler.rb +1 -1
  19. data/lib/ardm/ar/predicate_builder.rb +19 -0
  20. data/lib/ardm/{active_record → ar}/property.rb +2 -2
  21. data/lib/ardm/{active_record → ar}/query.rb +2 -2
  22. data/lib/ardm/{active_record → ar}/record.rb +4 -4
  23. data/lib/ardm/{active_record → ar}/relation.rb +2 -2
  24. data/lib/ardm/{active_record → ar}/repository.rb +2 -2
  25. data/lib/ardm/{active_record → ar}/serialization.rb +1 -1
  26. data/lib/ardm/{active_record → ar}/storage_names.rb +2 -2
  27. data/lib/ardm/{active_record → ar}/validations.rb +7 -7
  28. data/lib/ardm/{active_record.rb → ar.rb} +9 -7
  29. data/lib/ardm/dm/collection.rb +27 -0
  30. data/lib/ardm/{data_mapper → dm}/record.rb +23 -3
  31. data/lib/ardm/dm.rb +14 -0
  32. data/lib/ardm/version.rb +1 -1
  33. data/lib/ardm.rb +100 -50
  34. data/spec/ardm/datamapper_constants_spec.rb +1 -1
  35. data/spec/spec_helper.rb +13 -5
  36. data/spec/support/logger.rb +3 -3
  37. metadata +31 -33
  38. data/lib/ardm/active_record/base.rb +0 -53
  39. data/lib/ardm/active_record/data_mapper_constant.rb +0 -1
  40. data/lib/ardm/active_record/finalize.rb +0 -19
  41. data/lib/ardm/active_record/predicate_builder.rb +0 -19
  42. data/lib/ardm/data_mapper/collection.rb +0 -18
  43. data/lib/ardm/data_mapper.rb +0 -10
  44. data/lib/ardm/env.rb +0 -5
  45. data/lib/ardm/record.rb +0 -1
data/Gemfile CHANGED
@@ -8,13 +8,16 @@ gem 'awesome_print'
8
8
 
9
9
  group :test do
10
10
  gem 'sqlite3'
11
- gem 'activerecord', '~> 4.0.0'
12
11
  gem 'addressable'
13
12
  gem 'database_cleaner'
14
13
  gem 'rspec-its'
15
14
  end
16
15
 
17
- group :datamapper do
16
+ group :ar do
17
+ gem 'activerecord', '~> 4.0.0'
18
+ end
19
+
20
+ group :dm do
18
21
  gem 'dm-core', '~> 1.2'
19
22
  gem 'dm-sqlite-adapter', '~> 1.2'
20
23
  gem 'dm-types', '~> 1.2', git: "git://github.com/engineyard/dm-types.git", branch: "1.2-multijson"
data/README.md CHANGED
@@ -29,53 +29,58 @@ Lets examine some of the reasons why you might move to ActiveRecord.
29
29
 
30
30
  ## Installation
31
31
 
32
+ Near the top of your config/application.rb, add the following:
33
+
32
34
  require 'ardm'
35
+ Ardm.orm = ENV['ORM'] || :dm # default
33
36
 
34
- Run your project using the ORM environment variable.
37
+ Ardm.ar do # only executed if ORM is ActiveRecord
38
+ Bundler.require(:active_record) # libs related to active record
39
+ require "active_record/railtie"
40
+ end
41
+ Ardm.dm do # only executed if ORM is DataMapper
42
+ Bundler.require(:data_mapper) # libs related to data mapper
43
+ end
44
+ Ardm.setup # this requires the Ardm shim code
35
45
 
36
- ORM=activerecord bundle exec rake spec
37
- ORM=datamapper bundle exec rake spec
46
+ Next you need to change add a base class to EVERY model that previously
47
+ included DataMapper::Resource.
38
48
 
39
- ## Incremental migration from DataMapper to ActiveRecord
49
+ This is very tedious but there's no way around it. All ActiveRecord
50
+ models must inherit from ActiveRecord::Base, so Ardm creates an interchangeable
51
+ base class that can be either ActiveRecord or DataMapper.
40
52
 
41
- ActiveRecord requires your models to inherit from ActiveRecord::Base, which makes
42
- it difficult to approach this migration incrementally. All or nothing is a scary
43
- way to switch ORMs. To solve this, Ardm supplies Ardm::Record.
53
+ If your model is STI, add it to the base model.
44
54
 
45
- Ardm::Record will be the new base class. You'll need to search and replace
46
- all models that include DataMapper::Resource, remove it, and add Ardm::Record
47
- as the base class. If your model is STI, add it to the base model and remove
48
- DataMapper::Resource from all models.
55
+ I'm sorry, it's the only way.
49
56
 
50
- Example:
57
+ app/models/my_model.rb
51
58
 
52
- class MyModel
53
- include DataMapper::Resource
54
- # ...
59
+ class MyModel < Ardm::Record # <--- add this
60
+ include DataMapper::Resource # you can remove this (it should also be shimmed)
55
61
  end
56
62
 
57
- # The model above changes to:
63
+ Run your project using the ORM environment variable.
58
64
 
59
- class MyModel < Ardm::Record
60
- # ...
61
- end
65
+ # Try to get this one working now with the changes above.
66
+ ORM=dm bundle exec rake spec
62
67
 
63
- With this new base clase you can switch between ActiveRecord and DataMapper
64
- by flipping a swith in your application. This approach allows you to continue
65
- developing your application in DataMapper while you work on removing all
66
- the "datamapper-isms" from your code. This library attempts to take care of
67
- most DataMapper features, but there are probably tons of small variations
68
- that are not accounted for.
68
+ # This will fail horribly
69
+ ORM=ar bundle exec rake spec
69
70
 
70
- ## General Strategy
71
+ With this new base clase and the ORM environment variable, you can switch
72
+ between ActiveRecord and DataMapper by flipping the ORM variable.
71
73
 
72
- This is a complex thing to approach. I'm hoping this project can make this move
73
- into a repeatable strategy rather than everyone needing to create their own
74
- unique solution.
74
+ This approach allows you to continue developing your application in
75
+ DataMapper while you work on removing all the "datamapper-isms" from your
76
+ code. This library attempts to take care of most DataMapper features, but
77
+ there are probably tons of small variations that are not accounted for.
78
+
79
+ ## General Strategy
75
80
 
76
- 1. Get the application running with Ardm installed. Don't even think about
77
- ActiveRecord until you have Ardm working in DataMapper mode and you can
78
- deploy your application normally with ardm installed.
81
+ 1. Get the application running in DataMapper with Ardm installed. Don't even
82
+ think about ActiveRecord until you have Ardm working in DataMapper mode and
83
+ you can deploy your application normally with ardm installed.
79
84
  2. Start to remove references to `DataMapper` by using the conversions
80
85
  mentioned below. The idea is to remove the `DataMapper` constant completely
81
86
  so you can run without `dm-core` when in ActiveRecord mode.
@@ -89,11 +94,15 @@ unique solution.
89
94
  DataMapper specific code for ActiveRecord code. You can branch around
90
95
  picky code with the `Ardme.activerecord?` and `Ardm.datamapper?` helpers.
91
96
 
97
+ This is a complex thing to approach. I hope Ardm will make this change
98
+ into a repeatable strategy rather than everyone needing to create their own
99
+ unique solution.
100
+
92
101
  ## Conversions
93
102
 
94
103
  Things that access DataMapper directly can be replaced with Ardm invocations:
95
104
 
96
- DataMapper.finalize => Ardm::Record.finalize (no-op in AR mode)
105
+ DataMapper.finalize => Ardm::Record.finalize # this is still important for Ardm
97
106
  DataMapper.repository => Ardm::Record.repository
98
107
  DataMapper.logger => Ardm::Record.logger
99
108
 
@@ -110,12 +119,9 @@ adapters for accessing the same data through ActiveRecord.
110
119
  If you run into code that is particularly difficult to convert, you can
111
120
  duplicate the code and write a different version for each ORM:
112
121
 
113
- if Ardm.activerecord?
114
- Thing.where(Thing.arel_table[:field].matches('something'))
115
- else
116
- # This is just an example. This should actually work fine in Ardm.
117
- Thing.all(:field.like => 'something')
118
- end
122
+ Ardm.ar { Thing.where(Thing.arel_table[:field].matches('something')) }
123
+ # This is just an example. This should actually work fine in Ardm.
124
+ Ardm.dm { Thing.all(:field.like => 'something') }
119
125
 
120
126
  ## Copyright
121
127
 
@@ -1,7 +1,7 @@
1
1
 
2
2
 
3
3
  module Ardm
4
- module ActiveRecord
4
+ module Ar
5
5
  module Associations
6
6
  extend ActiveSupport::Concern
7
7
 
@@ -66,7 +66,7 @@ module Ardm
66
66
  end
67
67
  end
68
68
 
69
- def belongs_to(field, *args)
69
+ def belongs_to(name, *args)
70
70
  options = args.shift || {}
71
71
 
72
72
  if String === options || Class === options # belongs_to :name, 'Class', options: 'here'
@@ -74,20 +74,38 @@ module Ardm
74
74
  end
75
75
 
76
76
  unless Hash === options
77
- raise ArgumentError, "bad belongs_to #{field} options format #{options.inspect}"
77
+ raise ArgumentError, "bad belongs_to #{name} options format #{options.inspect}"
78
+ end
79
+
80
+ if options.has_key?(:key) || options.has_key?(:unique)
81
+ raise Ardm::NotImplemented, "belongs to :key and :unique are not implemented."
78
82
  end
79
83
 
80
84
  options.delete(:default)
81
- options.delete(:required)
82
- opts = Ardm::ActiveRecord::Associations.convert_options(self, options)
83
- super field, *opts
84
- klass = self
85
- Ardm::ActiveRecord::Finalize.on_finalize do
86
- assoc = reflect_on_association(field)
87
- klass.class_eval do
88
- # @todo String is a hack... hoping AR can convert strings to integers during save for integer keys.
89
- property assoc.foreign_key, assoc.primary_key_column.sql_type == "Integer" ? Integer : String, key: false
85
+ required = options.delete(:required)
86
+ opts = Ardm::Ar::Associations.convert_options(self, options)
87
+ super name, *opts
88
+
89
+ model = self
90
+ Ardm::Ar::Finalize.on_finalize do
91
+ return @child_key if defined?(@child_key)
92
+
93
+ properties = model.properties
94
+ assoc = reflect_on_association(name)
95
+
96
+ property_name = assoc.foreign_key
97
+ target_property = assoc.klass.properties.key.first
98
+
99
+ properties[property_name] || begin
100
+ source_key_options = Ardm::Ext::Hash.only(target_property.options, :length, :precision, :scale, :min, :max).update(
101
+ :index => name,
102
+ :required => (required == false ? false : true),
103
+ :key => false,
104
+ :unique => false
105
+ )
106
+ model.property(property_name, target_property.to_child_key, source_key_options)
90
107
  end
108
+
91
109
  end
92
110
  nil
93
111
  end
@@ -107,8 +125,8 @@ module Ardm
107
125
  raise ArgumentError, "bad has #{count} options format #{options.inspect}"
108
126
  end
109
127
 
110
- options[:order] = Ardm::ActiveRecord::Query.order(self, options[:order]) if options[:order]
111
- opts = Ardm::ActiveRecord::Associations.convert_options(self, options, :through, :order, :source)
128
+ options[:order] = Ardm::Ar::Query.order(self, options[:order]) if options[:order]
129
+ opts = Ardm::Ar::Associations.convert_options(self, options, :through, :order, :source)
112
130
 
113
131
  case count
114
132
  when 1 then has_one name, *opts
@@ -0,0 +1,53 @@
1
+ require 'active_support/concern'
2
+
3
+ require 'ardm/ar/associations'
4
+ require 'ardm/ar/dirty'
5
+ require 'ardm/ar/finalize'
6
+ require 'ardm/ar/hooks'
7
+ require 'ardm/ar/is'
8
+ require 'ardm/ar/inheritance'
9
+ require 'ardm/ar/persistence'
10
+ require 'ardm/ar/property'
11
+ require 'ardm/ar/query'
12
+ require 'ardm/ar/repository'
13
+ require 'ardm/ar/storage_names'
14
+ require 'ardm/ar/validations'
15
+
16
+ module Ardm
17
+ module Ar
18
+ # Include all the Ardm modules.
19
+ #
20
+ # You can use this directly if you want your own abstract base class.
21
+ #
22
+ # require 'ardm/active_record/base'
23
+ #
24
+ # class MyRecord < ActiveRecord::Base
25
+ # include Ardm::Ar::Base
26
+ # end
27
+ #
28
+ # Or Ardm::ActiveRecord::Base is built in to Ardm::Record
29
+ #
30
+ # require 'ardm/active_record/record'
31
+ #
32
+ # class MyRecord < Ardm::Record
33
+ # # already included
34
+ # end
35
+ #
36
+ module Base
37
+ extend ActiveSupport::Concern
38
+
39
+ include Ardm::Ar::Associations
40
+ include Ardm::Ar::Finalize
41
+ include Ardm::Ar::Hooks
42
+ include Ardm::Ar::Dirty
43
+ include Ardm::Ar::Is
44
+ include Ardm::Ar::Inheritance
45
+ include Ardm::Ar::Persistence
46
+ include Ardm::Ar::Property
47
+ include Ardm::Ar::Query
48
+ include Ardm::Ar::Repository
49
+ include Ardm::Ar::StorageNames
50
+ include Ardm::Ar::Validations
51
+ end
52
+ end
53
+ end
File without changes
@@ -0,0 +1 @@
1
+ ::DataMapper = Ardm::Ar::DataMapperConstantProxy
@@ -1,5 +1,5 @@
1
1
  module Ardm
2
- module ActiveRecord
2
+ module Ar
3
3
  module DataMapperConstantProxy
4
4
 
5
5
  class << self
@@ -1,5 +1,5 @@
1
1
  module Ardm
2
- module ActiveRecord
2
+ module Ar
3
3
  module Dirty
4
4
  def dirty?
5
5
  changed?
@@ -0,0 +1,26 @@
1
+ module Ardm
2
+ module Ar
3
+ module Finalize
4
+ extend ActiveSupport::Concern
5
+
6
+ def self.finalizers
7
+ @finalizers ||= []
8
+ end
9
+
10
+ def self.on_finalize(&block)
11
+ return unless block_given?
12
+ finalizers << block
13
+ end
14
+
15
+ def self.finalize
16
+ Ardm::Ar::Finalize.finalizers.each { |f| f.call }
17
+ end
18
+
19
+ module ClassMethods
20
+ def finalize
21
+ Ardm::Ar::Finalize.finalize
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -1,7 +1,7 @@
1
1
  require 'active_support/concern'
2
2
 
3
3
  module Ardm
4
- module ActiveRecord
4
+ module Ar
5
5
  module Hooks
6
6
  extend ActiveSupport::Concern
7
7
 
@@ -1,7 +1,7 @@
1
1
  require 'active_support/concern'
2
2
 
3
3
  module Ardm
4
- module ActiveRecord
4
+ module Ar
5
5
  module Inheritance
6
6
  extend ActiveSupport::Concern
7
7
 
@@ -1,5 +1,5 @@
1
1
  module Ardm
2
- module ActiveRecord
2
+ module Ar
3
3
  module Is
4
4
  module StateMachine
5
5
  extend ActiveSupport::Concern
@@ -1,8 +1,8 @@
1
1
  require 'active_support/concern'
2
- require 'ardm/active_record/is/state_machine'
2
+ require 'ardm/ar/is/state_machine'
3
3
 
4
4
  module Ardm
5
- module ActiveRecord
5
+ module Ar
6
6
  module Is
7
7
  extend ActiveSupport::Concern
8
8
 
@@ -10,7 +10,7 @@ module Ardm
10
10
  def is(target, options={}, &block)
11
11
  case target
12
12
  when :state_machine
13
- include Ardm::ActiveRecord::Is::StateMachine
13
+ include Ardm::Ar::Is::StateMachine
14
14
  is_state_machine(options, &block)
15
15
  else
16
16
  STDERR.puts "TODO: #{self} is #{target.inspect}, #{options.inspect}"
@@ -1,7 +1,7 @@
1
1
  require 'active_support/concern'
2
2
 
3
3
  module Ardm
4
- module ActiveRecord
4
+ module Ar
5
5
  module Persistence
6
6
  extend ActiveSupport::Concern
7
7
 
@@ -1,5 +1,5 @@
1
1
  module Ardm
2
- module ActiveRecord
2
+ module Ar
3
3
  module PredicateBuilder
4
4
  class ArrayHandler # :nodoc:
5
5
  def call(attribute, value)
@@ -1,7 +1,7 @@
1
1
  require 'active_support/concern'
2
2
 
3
3
  module Ardm
4
- module ActiveRecord
4
+ module Ar
5
5
  module PredicateBuilder
6
6
  module Rails3
7
7
  extend ActiveSupport::Concern
@@ -1,7 +1,7 @@
1
1
  require 'active_support/concern'
2
2
 
3
3
  module Ardm
4
- module ActiveRecord
4
+ module Ar
5
5
  module PredicateBuilder
6
6
  module Rails4
7
7
  extend ActiveSupport::Concern
@@ -1,5 +1,5 @@
1
1
  module Ardm
2
- module ActiveRecord
2
+ module Ar
3
3
  module PredicateBuilder
4
4
  class RelationHandler # :nodoc:
5
5
  def call(attribute, value)
@@ -0,0 +1,19 @@
1
+ require 'active_record/relation/predicate_builder' # force it to load
2
+
3
+ require 'ardm/ar/predicate_builder/relation_handler'
4
+ require 'ardm/ar/predicate_builder/array_handler'
5
+
6
+ if ::ActiveRecord::PredicateBuilder.respond_to? :expand
7
+ require 'ardm/ar/predicate_builder/rails4'
8
+ ::ActiveRecord::PredicateBuilder.send(:include, Ardm::Ar::PredicateBuilder::Rails4)
9
+ else
10
+ require 'ardm/ar/predicate_builder/rails3'
11
+ ::ActiveRecord::PredicateBuilder.send(:include, Ardm::Ar::PredicateBuilder::Rails3)
12
+ end
13
+
14
+ ::ActiveRecord::PredicateBuilder.class_eval do
15
+ # calls super instead of calling the method on the class
16
+ class << self
17
+ remove_method :build_from_hash
18
+ end
19
+ end
@@ -2,13 +2,13 @@ require 'active_support/concern'
2
2
  require 'ardm/property/lookup'
3
3
 
4
4
  module Ardm
5
- module ActiveRecord
5
+ module Ar
6
6
  module Property
7
7
  extend ActiveSupport::Concern
8
8
 
9
9
  included do
10
10
  extend Ardm::Property::Lookup
11
- extend Ardm::ActiveRecord::Property::ClassMethods
11
+ extend Ardm::Ar::Property::ClassMethods
12
12
 
13
13
  instance_variable_set(:@properties, Ardm::PropertySet.new)
14
14
  instance_variable_set(:@field_naming_convention, nil)
@@ -3,10 +3,10 @@ require 'active_support/concern'
3
3
  require 'ardm/query/expression'
4
4
  require 'ardm/query/operator'
5
5
  require 'ardm/query/ext/symbol'
6
- require 'ardm/active_record/predicate_builder'
6
+ require 'ardm/ar/predicate_builder'
7
7
 
8
8
  module Ardm
9
- module ActiveRecord
9
+ module Ar
10
10
  module Query
11
11
  extend ActiveSupport::Concern
12
12
 
@@ -1,11 +1,11 @@
1
1
  require 'active_record'
2
2
  require 'ardm'
3
- require 'ardm/active_record/base'
3
+ require 'ardm/ar/base'
4
4
 
5
5
  module Ardm
6
- module ActiveRecord
6
+ module Ar
7
7
  class Record < ::ActiveRecord::Base
8
- include Ardm::ActiveRecord::Base
8
+ include Ardm::Ar::Base
9
9
 
10
10
  self.abstract_class = true
11
11
 
@@ -15,7 +15,7 @@ module Ardm
15
15
  attr_accessible prop.name
16
16
  attr_accessible prop.field
17
17
  rescue => e
18
- puts "WARNING: `attr_accessible` not found. Include 'protected_attributes' gem in rails >= 4 (or if you need it).\n#{e}" unless $attr_accessible_warning
18
+ puts "WARNING: `attr_accessible` not found. Include 'protected_attributes' gem in rails >= 4 (if you need it).\n#{e}" unless $attr_accessible_warning
19
19
  $attr_accessible_warning = true
20
20
  end
21
21
  prop
@@ -1,8 +1,8 @@
1
1
  require 'active_support/concern'
2
- require 'ardm/active_record/collection'
2
+ require 'ardm/ar/collection'
3
3
 
4
4
  module Ardm
5
- module ActiveRecord
5
+ module Ar
6
6
  module Relation
7
7
  extend ActiveSupport::Concern
8
8
 
@@ -1,7 +1,7 @@
1
1
  require 'active_support/concern'
2
2
 
3
3
  module Ardm
4
- module ActiveRecord
4
+ module Ar
5
5
  module Repository
6
6
  extend ActiveSupport::Concern
7
7
 
@@ -18,7 +18,7 @@ module Ardm
18
18
  if block_given?
19
19
  yield
20
20
  else
21
- Ardm::ActiveRecord::Repository::Proxy.new self
21
+ Ardm::Ar::Repository::Proxy.new self
22
22
  end
23
23
  end
24
24
  end
@@ -1,7 +1,7 @@
1
1
  require 'active_support/concern'
2
2
 
3
3
  module Ardm
4
- module ActiveRecord
4
+ module Ar
5
5
  module Serialization
6
6
  extend ActiveSupport::Concern
7
7
 
@@ -1,13 +1,13 @@
1
1
  require 'active_support/concern'
2
2
 
3
3
  module Ardm
4
- module ActiveRecord
4
+ module Ar
5
5
  module StorageNames
6
6
  extend ActiveSupport::Concern
7
7
 
8
8
  module ClassMethods
9
9
  def storage_names
10
- Ardm::ActiveRecord::StorageNames::Proxy.new(self)
10
+ Ardm::Ar::StorageNames::Proxy.new(self)
11
11
  end
12
12
  end
13
13
 
@@ -2,7 +2,7 @@ require 'active_support/concern'
2
2
  require 'active_model/validations'
3
3
 
4
4
  module Ardm
5
- module ActiveRecord
5
+ module Ar
6
6
  # Extend ActiveRecord to support DataMapper validations
7
7
  module Validations
8
8
  extend ActiveSupport::Concern
@@ -34,22 +34,22 @@ module Ardm
34
34
  module ClassMethods
35
35
 
36
36
  def validates_belongs_to(*fields)
37
- fields, options = Ardm::ActiveRecord::Validations.extract_options(fields)
37
+ fields, options = Ardm::Ar::Validations.extract_options(fields)
38
38
  validates *fields, presence: options
39
39
  end
40
40
 
41
41
  def validates_presence_of(*fields)
42
- fields, options = Ardm::ActiveRecord::Validations.extract_options(fields)
42
+ fields, options = Ardm::Ar::Validations.extract_options(fields)
43
43
  validates *fields, presence: options
44
44
  end
45
45
 
46
46
  def validates_length_of(*fields)
47
- fields, options = Ardm::ActiveRecord::Validations.extract_options(fields, :in, :within, :maximum, :minimum, :is)
47
+ fields, options = Ardm::Ar::Validations.extract_options(fields, :in, :within, :maximum, :minimum, :is)
48
48
  validates *fields, length: options
49
49
  end
50
50
 
51
51
  def validates_uniqueness_of(*fields)
52
- fields, options = Ardm::ActiveRecord::Validations.extract_options(fields, :scope)
52
+ fields, options = Ardm::Ar::Validations.extract_options(fields, :scope)
53
53
  fields = fields.map do |field|
54
54
  if property = properties[field]
55
55
  property.field
@@ -71,7 +71,7 @@ module Ardm
71
71
  end
72
72
 
73
73
  def validates_within(*fields)
74
- fields, options = Ardm::ActiveRecord::Validations.extract_options(fields, :in)
74
+ fields, options = Ardm::Ar::Validations.extract_options(fields, :in)
75
75
  validates *fields, inclusion: options
76
76
  end
77
77
 
@@ -81,7 +81,7 @@ module Ardm
81
81
  # validates_with_method :attr, method: :method_name
82
82
  # validates_with_method :method_name, options: "here"
83
83
  def validates_with_method(*fields)
84
- fields, options = Ardm::ActiveRecord::Validations.extract_options(fields, :method)
84
+ fields, options = Ardm::Ar::Validations.extract_options(fields, :method)
85
85
 
86
86
  # validates_with_method :attr, :method_name
87
87
  att, meth = *fields
@@ -26,20 +26,22 @@ require 'ardm/support/descendant_set'
26
26
  require 'active_record'
27
27
  require 'active_record/relation'
28
28
 
29
- require 'ardm/active_record/record'
30
- require 'ardm/active_record/relation'
31
- require 'ardm/active_record/data_mapper_constant_proxy'
29
+ require 'ardm/ar/record'
30
+ require 'ardm/ar/relation'
31
+ require 'ardm/ar/data_mapper_constant_proxy'
32
+ require 'ardm/ar/validations'
32
33
 
33
34
  module Ardm
34
- Record = Ardm::ActiveRecord::Record
35
+ Record = Ardm::Ar::Record
36
+ Validations = Ardm::Ar::Validations
35
37
  SaveFailureError = ::ActiveRecord::RecordNotSaved
36
- RecordNotFound = ::ActiveRecord::RecordNotFound
38
+ RecordNotFound = ::ActiveRecord::RecordNotFound
37
39
 
38
40
  def self.define_datamapper_constant!
39
- require 'ardm/active_record/data_mapper_constant'
41
+ require 'ardm/ar/data_mapper_constant'
40
42
  end
41
43
  end
42
44
 
43
45
  ::ActiveRecord::Relation.class_eval do
44
- include Ardm::ActiveRecord::Relation
46
+ include Ardm::Ar::Relation
45
47
  end
@@ -0,0 +1,27 @@
1
+ module Ardm::Dm
2
+ module RelationChain
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ alias_method :old_delegate_to_relationship, :delegate_to_relationship
7
+ end
8
+
9
+ def delegate_to_relationship(relationship, query = nil)
10
+ Ardm::Deprecation.warn("Relation chain #{model.name}.#{relationship.name}")
11
+ old_delegate_to_relationship(relationship, query)
12
+ end
13
+
14
+ def includes(*)
15
+ self
16
+ end
17
+
18
+ def references(*)
19
+ self
20
+ end
21
+ end
22
+ end
23
+
24
+ DataMapper::Collection.class_eval do
25
+ include Ardm::Dm::RelationChain
26
+ end
27
+
@@ -1,14 +1,34 @@
1
1
  require 'active_support/concern'
2
2
  require 'dm-core'
3
- require 'ardm/data_mapper/collection'
3
+ require 'ardm/dm/collection'
4
4
 
5
5
  module Ardm
6
- module DataMapper
6
+ module Dm
7
7
  class Record
8
8
  def self.inherited(base)
9
- base.send(:include, ::DataMapper::Resource)
9
+ @on_inherited.each { |block| base.class_eval(&block) }
10
10
  end
11
11
 
12
+ def self.on_inherited(&block)
13
+ if Ardm::Dm::Record == self
14
+ @on_inherited ||= []
15
+ @on_inherited << block
16
+ @on_inherited
17
+ else
18
+ class_eval(&block)
19
+ end
20
+ end
21
+
22
+ class << self
23
+ alias __include_after_inherited__ include
24
+ end
25
+
26
+ def self.include(mod)
27
+ on_inherited { __include_after_inherited__ mod }
28
+ end
29
+
30
+ include ::DataMapper::Resource
31
+
12
32
  def self.finalize
13
33
  ::DataMapper.finalize
14
34
  end
data/lib/ardm/dm.rb ADDED
@@ -0,0 +1,14 @@
1
+ require 'ardm'
2
+
3
+ require 'dm-core'
4
+ require 'ardm/dm/record'
5
+ require 'ardm/dm/collection'
6
+
7
+ module Ardm
8
+ Record = Ardm::Dm::Record
9
+ Validations = ::DataMapper::Validations
10
+ SaveFailureError = ::DataMapper::SaveFailureError
11
+ RecordNotFound = ::DataMapper::ObjectNotFoundError
12
+ Property = ::DataMapper::Property
13
+ Collection = ::DataMapper::Collection
14
+ end
data/lib/ardm/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Ardm
2
- VERSION = '0.2.7'
2
+ VERSION = '0.3.0'
3
3
  end
data/lib/ardm.rb CHANGED
@@ -3,65 +3,115 @@ require 'ardm/deprecation'
3
3
  module Ardm
4
4
  NotImplemented = Class.new(RuntimeError)
5
5
 
6
- # Check which ORM is loaded in Ardm.
7
- #
8
- # @api public
9
- def self.orm
10
- @orm ||= :active_record
11
- end
6
+ class << self
12
7
 
13
- # Set which orm to load.
14
- #
15
- # @api public
16
- def self.orm=(orm)
17
- if defined?(Ardm::ActiveRecord) || defined?(Ardm::DataMapper)
18
- raise "Cannot change Ardm.orm when #{orm} libs are already loaded."
8
+ # Setup the ORM using orm arg or $ORM, then require the correct shim libs.
9
+ #
10
+ # If an ORM is not specified as an argument, ENV['ORM'] will be used.
11
+ # If $ORM is not set, then Ardm will raise.
12
+ #
13
+ # Execute the block if one is given. This is a good time to require
14
+ # active_record or dm-core using Ardm.ar or Ardm.dm blocks.
15
+ #
16
+ # Ardm.setup ENV['ORM'] do
17
+ # Ardm.ar do
18
+ # Bundler.require(:active_record)
19
+ # require "active_record/railtie"
20
+ # end
21
+ # Ardm.dm { Bundler.require(:data_mapper) }
22
+ # end
23
+ #
24
+ # The Ardm shim libs will be required after the block returns.
25
+ #
26
+ # @api public
27
+ def setup(orm=nil)
28
+ self.orm = orm if orm
29
+ yield self if block_given?
30
+ require lib
19
31
  end
20
32
 
21
- @orm = case orm.to_s
22
- when /active_?record/, '' then :active_record
23
- when /data_?mapper/ then :data_mapper
24
- else raise "Unknown ENV['ORM']: #{ENV['ORM']}"
25
- end
26
- end
33
+ # Check which ORM is loaded in Ardm.
34
+ #
35
+ # @api public
36
+ def orm
37
+ if @orm
38
+ return @orm
39
+ else
40
+ self.orm = ENV['ORM']
41
+ end
42
+ @orm
43
+ end
27
44
 
28
- # Return true if Ardm has loaded ActiveRecord ORM.
29
- #
30
- # @api public
31
- def self.active_record?
32
- orm == :active_record
33
- end
45
+ # Set which orm to load.
46
+ #
47
+ # @api public
48
+ def orm=(orm)
49
+ neworm =
50
+ case orm.to_s
51
+ when /(ar|active_?record)/ then :ar
52
+ when /(dm|data_?mapper)/ then :dm
53
+ when "" then raise "Specify Ardm.orm by assigning :ar or :dm or by setting ENV['ORM']"
54
+ else raise "Unknown Ardm.orm. Expected: (ar|dm). Got: #{orm.inspect}"
55
+ end
34
56
 
35
- # Return true if Ardm has loaded DataMapper ORM.
36
- #
37
- # @api public
38
- def self.data_mapper?
39
- orm == :data_mapper
40
- end
57
+ if @orm == neworm
58
+ return @orm
59
+ end
41
60
 
42
- # Yield if Ardm has loaded ActiveRecord ORM.
43
- #
44
- # @api public
45
- def self.active_record
46
- yield if block_given? && active_record?
47
- end
61
+ if defined?(Ardm::Ar) || defined?(Ardm::Dm)
62
+ raise "Cannot change Ardm.orm when #{self.orm} libs are already loaded."
63
+ end
48
64
 
49
- def self.rails3?
50
- self.active_record? && ::ActiveRecord::VERSION::STRING >= "3.0" && ::ActiveRecord::VERSION::STRING <= "4.0"
51
- end
65
+ @orm = neworm
66
+ end
52
67
 
53
- def self.rails4?
54
- self.active_record? && !self.rails3?
55
- end
68
+ def lib
69
+ "ardm/#{orm}"
70
+ end
56
71
 
57
- # Yield if Ardm has loaded DataMapper ORM.
58
- #
59
- # @api public
60
- def self.data_mapper
61
- yield if block_given? && data_mapper?
62
- end
72
+ # Return true if Ardm has loaded ActiveRecord ORM.
73
+ #
74
+ # @api public
75
+ def ar?
76
+ orm == :ar
77
+ end
78
+ alias activerecord? ar?
79
+ alias active_record? ar?
80
+
81
+ # Return true if Ardm has loaded DataMapper ORM.
82
+ #
83
+ # @api public
84
+ def dm?
85
+ orm == :dm
86
+ end
87
+ alias datamapper? dm?
88
+ alias data_mapper? dm?
63
89
 
64
- def self.lib
65
- "ardm/#{orm}"
90
+ # Yield if Ardm has loaded ActiveRecord ORM.
91
+ #
92
+ # @api public
93
+ def ar
94
+ yield if block_given? && ar?
95
+ end
96
+ alias activerecord ar
97
+ alias active_record ar
98
+
99
+ # Yield if Ardm has loaded DataMapper ORM.
100
+ #
101
+ # @api public
102
+ def dm
103
+ yield if block_given? && dm?
104
+ end
105
+
106
+ alias datamapper dm
107
+ alias data_mapper dm
108
+
109
+ def rails3?
110
+ ar? && ::ActiveRecord::VERSION::STRING >= "3.0" && ::ActiveRecord::VERSION::STRING <= "4.0"
111
+ end
112
+
113
+ def rails4?
114
+ ar? && !rails3?
115
+ end
66
116
  end
67
117
  end
@@ -1,6 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe Ardm::ActiveRecord::DataMapperConstantProxy do
3
+ describe Ardm::Ar::DataMapperConstantProxy do
4
4
  it 'defines Resource' do
5
5
  expect(described_class::Resource).to be_kind_of(Module)
6
6
  end
data/spec/spec_helper.rb CHANGED
@@ -1,11 +1,15 @@
1
- Bundler.require(:default, :test)
1
+ #Bundler.require(:default, :test)
2
+ require 'rspec'
2
3
 
3
- ENV['ORM'] ||= 'active_record'
4
- require 'ardm/env'
4
+ require 'ardm'
5
+ Ardm.orm = ENV['ORM'] || 'active_record'
6
+ Ardm.setup
7
+
8
+ require 'database_cleaner'
5
9
 
6
10
  Dir["#{Pathname(__FILE__).dirname.expand_path}/{shared,support}/*.rb"].each { |file| require file }
7
11
 
8
- Ardm.active_record do
12
+ Ardm.ar do
9
13
  ActiveRecord::Base.configurations = { "ardm" => {
10
14
  "database" => "db/test.sqlite",
11
15
  "adapter" => "sqlite3"
@@ -20,12 +24,16 @@ Ardm.active_record do
20
24
  end
21
25
  end
22
26
 
23
- Ardm.data_mapper do
27
+ Ardm.dm do
24
28
  Bundler.require(:datamapper)
25
29
  DataMapper.setup(:default, "sqlite3://#{File.expand_path("../../db/test.sqlite", __FILE__)}")
26
30
  DataMapper.auto_migrate!
27
31
  end
28
32
 
33
+ Dir["#{Pathname(__FILE__).dirname.expand_path}/fixtures/*.rb"].each { |file| require file }
34
+
35
+ Ardm::Record.finalize
36
+
29
37
  RSpec.configure do |config|
30
38
  config.treat_symbols_as_metadata_keys_with_true_values = true
31
39
  if ENV["ORM"] == "active_record"
@@ -1,7 +1,7 @@
1
1
  if defined?(::DataMapper)
2
- module DataMapper::LogListener
2
+ module ::DataMapper::LogListener
3
3
  def log(message)
4
- DataMapper.logger.info("#{message.query}")
4
+ ::DataMapper.logger.info("#{message.query}")
5
5
  super
6
6
  rescue Exception => e
7
7
  ::DataMapper.logger.error "[datamapper] #{e.class.name}: #{e.message}: #{message.inspect}}"
@@ -27,7 +27,7 @@ RSpec.configure do |config|
27
27
  require 'active_support/inflector'
28
28
  driver = DataObjects.const_get(ActiveSupport::Inflector.camelize('sqlite3'), false)
29
29
 
30
- DataObjects::Connection.send(:include, DataMapper::LogListener)
30
+ DataObjects::Connection.send(:include, ::DataMapper::LogListener)
31
31
  # FIXME Setting DataMapper::Logger.new($stdout, :off) alone won't work because the #log
32
32
  # method is currently only available in DO and needs an explicit DO Logger instantiated.
33
33
  # We turn the logger :off because ActiveSupport::Notifications handles displaying log messages
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ardm
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.7
4
+ version: 0.3.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2015-01-14 00:00:00.000000000 Z
13
+ date: 2015-01-22 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: activesupport
@@ -182,37 +182,36 @@ files:
182
182
  - ardm.gemspec
183
183
  - db/.gitignore
184
184
  - lib/ardm.rb
185
- - lib/ardm/active_record.rb
186
- - lib/ardm/active_record/associations.rb
187
- - lib/ardm/active_record/base.rb
188
- - lib/ardm/active_record/collection.rb
189
- - lib/ardm/active_record/data_mapper_constant.rb
190
- - lib/ardm/active_record/data_mapper_constant_proxy.rb
191
- - lib/ardm/active_record/dirty.rb
192
- - lib/ardm/active_record/finalize.rb
193
- - lib/ardm/active_record/hooks.rb
194
- - lib/ardm/active_record/inheritance.rb
195
- - lib/ardm/active_record/is.rb
196
- - lib/ardm/active_record/is/state_machine.rb
197
- - lib/ardm/active_record/persistence.rb
198
- - lib/ardm/active_record/predicate_builder.rb
199
- - lib/ardm/active_record/predicate_builder/array_handler.rb
200
- - lib/ardm/active_record/predicate_builder/rails3.rb
201
- - lib/ardm/active_record/predicate_builder/rails4.rb
202
- - lib/ardm/active_record/predicate_builder/relation_handler.rb
203
- - lib/ardm/active_record/property.rb
204
- - lib/ardm/active_record/query.rb
205
- - lib/ardm/active_record/record.rb
206
- - lib/ardm/active_record/relation.rb
207
- - lib/ardm/active_record/repository.rb
208
- - lib/ardm/active_record/serialization.rb
209
- - lib/ardm/active_record/storage_names.rb
210
- - lib/ardm/active_record/validations.rb
211
- - lib/ardm/data_mapper.rb
212
- - lib/ardm/data_mapper/collection.rb
213
- - lib/ardm/data_mapper/record.rb
185
+ - lib/ardm/ar.rb
186
+ - lib/ardm/ar/associations.rb
187
+ - lib/ardm/ar/base.rb
188
+ - lib/ardm/ar/collection.rb
189
+ - lib/ardm/ar/data_mapper_constant.rb
190
+ - lib/ardm/ar/data_mapper_constant_proxy.rb
191
+ - lib/ardm/ar/dirty.rb
192
+ - lib/ardm/ar/finalize.rb
193
+ - lib/ardm/ar/hooks.rb
194
+ - lib/ardm/ar/inheritance.rb
195
+ - lib/ardm/ar/is.rb
196
+ - lib/ardm/ar/is/state_machine.rb
197
+ - lib/ardm/ar/persistence.rb
198
+ - lib/ardm/ar/predicate_builder.rb
199
+ - lib/ardm/ar/predicate_builder/array_handler.rb
200
+ - lib/ardm/ar/predicate_builder/rails3.rb
201
+ - lib/ardm/ar/predicate_builder/rails4.rb
202
+ - lib/ardm/ar/predicate_builder/relation_handler.rb
203
+ - lib/ardm/ar/property.rb
204
+ - lib/ardm/ar/query.rb
205
+ - lib/ardm/ar/record.rb
206
+ - lib/ardm/ar/relation.rb
207
+ - lib/ardm/ar/repository.rb
208
+ - lib/ardm/ar/serialization.rb
209
+ - lib/ardm/ar/storage_names.rb
210
+ - lib/ardm/ar/validations.rb
214
211
  - lib/ardm/deprecation.rb
215
- - lib/ardm/env.rb
212
+ - lib/ardm/dm.rb
213
+ - lib/ardm/dm/collection.rb
214
+ - lib/ardm/dm/record.rb
216
215
  - lib/ardm/property.rb
217
216
  - lib/ardm/property/api_key.rb
218
217
  - lib/ardm/property/bcrypt_hash.rb
@@ -256,7 +255,6 @@ files:
256
255
  - lib/ardm/query/expression.rb
257
256
  - lib/ardm/query/ext/symbol.rb
258
257
  - lib/ardm/query/operator.rb
259
- - lib/ardm/record.rb
260
258
  - lib/ardm/support/assertions.rb
261
259
  - lib/ardm/support/deprecate.rb
262
260
  - lib/ardm/support/descendant_set.rb
@@ -1,53 +0,0 @@
1
- require 'active_support/concern'
2
-
3
- require 'ardm/active_record/associations'
4
- require 'ardm/active_record/dirty'
5
- require 'ardm/active_record/finalize'
6
- require 'ardm/active_record/hooks'
7
- require 'ardm/active_record/is'
8
- require 'ardm/active_record/inheritance'
9
- require 'ardm/active_record/persistence'
10
- require 'ardm/active_record/property'
11
- require 'ardm/active_record/query'
12
- require 'ardm/active_record/repository'
13
- require 'ardm/active_record/storage_names'
14
- require 'ardm/active_record/validations'
15
-
16
- module Ardm
17
- module ActiveRecord
18
- # Include all the Ardm modules.
19
- #
20
- # You can use this directly if you want your own abstract base class.
21
- #
22
- # require 'ardm/active_record/base'
23
- #
24
- # class MyRecord < ActiveRecord::Base
25
- # include Ardm::ActiveRecord::Base
26
- # end
27
- #
28
- # Or Ardm::ActiveRecord::Base is built in to Ardm::Record
29
- #
30
- # require 'ardm/active_record/record'
31
- #
32
- # class MyRecord < Ardm::Record
33
- # # already included
34
- # end
35
- #
36
- module Base
37
- extend ActiveSupport::Concern
38
-
39
- include Ardm::ActiveRecord::Associations
40
- include Ardm::ActiveRecord::Finalize
41
- include Ardm::ActiveRecord::Hooks
42
- include Ardm::ActiveRecord::Dirty
43
- include Ardm::ActiveRecord::Is
44
- include Ardm::ActiveRecord::Inheritance
45
- include Ardm::ActiveRecord::Persistence
46
- include Ardm::ActiveRecord::Property
47
- include Ardm::ActiveRecord::Query
48
- include Ardm::ActiveRecord::Repository
49
- include Ardm::ActiveRecord::StorageNames
50
- include Ardm::ActiveRecord::Validations
51
- end
52
- end
53
- end
@@ -1 +0,0 @@
1
- ::DataMapper = Ardm::ActiveRecord::DataMapperConstantProxy
@@ -1,19 +0,0 @@
1
- module Ardm
2
- module ActiveRecord
3
- module Finalize
4
- extend ActiveSupport::Concern
5
-
6
- def self.on_finalize(&block)
7
- @on_finalize ||= []
8
- @on_finalize << block if block_given?
9
- @on_finalize
10
- end
11
-
12
- module ClassMethods
13
- def finalize
14
- Ardm::ActiveRecord::Finalize.on_finalize.each { |f| f.call }
15
- end
16
- end
17
- end
18
- end
19
- end
@@ -1,19 +0,0 @@
1
- require 'active_record/relation/predicate_builder' # force it to load
2
-
3
- require 'ardm/active_record/predicate_builder/relation_handler'
4
- require 'ardm/active_record/predicate_builder/array_handler'
5
-
6
- if ::ActiveRecord::PredicateBuilder.respond_to? :expand
7
- require 'ardm/active_record/predicate_builder/rails4'
8
- ::ActiveRecord::PredicateBuilder.send(:include, Ardm::ActiveRecord::PredicateBuilder::Rails4)
9
- else
10
- require 'ardm/active_record/predicate_builder/rails3'
11
- ::ActiveRecord::PredicateBuilder.send(:include, Ardm::ActiveRecord::PredicateBuilder::Rails3)
12
- end
13
-
14
- ::ActiveRecord::PredicateBuilder.class_eval do
15
- # calls super instead of calling the method on the class
16
- class << self
17
- remove_method :build_from_hash
18
- end
19
- end
@@ -1,18 +0,0 @@
1
- DataMapper::Collection.class_eval do
2
-
3
- alias_method :old_delegate_to_relationship, :delegate_to_relationship
4
-
5
- def delegate_to_relationship(relationship, query = nil)
6
- Ardm::Deprecation.warn("Relation chain #{model.name}.#{relationship.name}")
7
- old_delegate_to_relationship(relationship, query)
8
- end
9
-
10
- def includes(*)
11
- self
12
- end
13
-
14
- def references(*)
15
- self
16
- end
17
- end
18
-
@@ -1,10 +0,0 @@
1
- require 'ardm'
2
- require 'ardm/data_mapper/record'
3
-
4
- module Ardm
5
- Record = Ardm::DataMapper::Record
6
- SaveFailureError = ::DataMapper::SaveFailureError
7
- RecordNotFound = ::DataMapper::ObjectNotFoundError
8
- Property = ::DataMapper::Property
9
- Collection = ::DataMapper::Collection
10
- end
data/lib/ardm/env.rb DELETED
@@ -1,5 +0,0 @@
1
- # Load Ardm based on the $ORM environment variable.
2
- #
3
- require 'ardm'
4
- Ardm.orm = ENV['ORM']
5
- require Ardm.lib
data/lib/ardm/record.rb DELETED
@@ -1 +0,0 @@
1
- require "ardm/#{Ardm.orm}/record"