mongo_mapper 0.8.6 → 0.9.0

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 (107) hide show
  1. data/UPGRADES +10 -0
  2. data/bin/mmconsole +0 -1
  3. data/examples/identity_map/automatic.rb +1 -7
  4. data/examples/plugins.rb +9 -9
  5. data/examples/safe.rb +43 -0
  6. data/lib/mongo_mapper.rb +46 -33
  7. data/lib/mongo_mapper/document.rb +33 -32
  8. data/lib/mongo_mapper/embedded_document.rb +22 -22
  9. data/lib/mongo_mapper/locale/en.yml +5 -0
  10. data/lib/mongo_mapper/middleware/identity_map.rb +16 -0
  11. data/lib/mongo_mapper/plugins.rb +16 -3
  12. data/lib/mongo_mapper/plugins/accessible.rb +2 -0
  13. data/lib/mongo_mapper/plugins/active_model.rb +18 -0
  14. data/lib/mongo_mapper/plugins/associations.rb +37 -42
  15. data/lib/mongo_mapper/plugins/associations/base.rb +14 -50
  16. data/lib/mongo_mapper/plugins/associations/belongs_to_association.rb +58 -0
  17. data/lib/mongo_mapper/plugins/associations/belongs_to_polymorphic_proxy.rb +6 -1
  18. data/lib/mongo_mapper/plugins/associations/belongs_to_proxy.rb +30 -2
  19. data/lib/mongo_mapper/plugins/associations/embedded_collection.rb +4 -0
  20. data/lib/mongo_mapper/plugins/associations/in_array_proxy.rb +12 -6
  21. data/lib/mongo_mapper/plugins/associations/many_association.rb +67 -0
  22. data/lib/mongo_mapper/plugins/associations/many_documents_proxy.rb +5 -5
  23. data/lib/mongo_mapper/plugins/associations/many_embedded_proxy.rb +1 -1
  24. data/lib/mongo_mapper/plugins/associations/one_association.rb +20 -0
  25. data/lib/mongo_mapper/plugins/associations/one_embedded_proxy.rb +5 -0
  26. data/lib/mongo_mapper/plugins/associations/one_proxy.rb +7 -7
  27. data/lib/mongo_mapper/plugins/associations/proxy.rb +2 -2
  28. data/lib/mongo_mapper/plugins/caching.rb +3 -1
  29. data/lib/mongo_mapper/plugins/callbacks.rb +12 -221
  30. data/lib/mongo_mapper/plugins/clone.rb +3 -1
  31. data/lib/mongo_mapper/plugins/dirty.rb +38 -91
  32. data/lib/mongo_mapper/plugins/document.rb +4 -2
  33. data/lib/mongo_mapper/plugins/dynamic_querying.rb +2 -0
  34. data/lib/mongo_mapper/plugins/embedded_callbacks.rb +43 -0
  35. data/lib/mongo_mapper/plugins/embedded_document.rb +16 -9
  36. data/lib/mongo_mapper/plugins/equality.rb +2 -0
  37. data/lib/mongo_mapper/plugins/identity_map.rb +4 -2
  38. data/lib/mongo_mapper/plugins/indexes.rb +2 -0
  39. data/lib/mongo_mapper/plugins/inspect.rb +3 -1
  40. data/lib/mongo_mapper/plugins/keys.rb +28 -22
  41. data/lib/mongo_mapper/plugins/keys/key.rb +12 -6
  42. data/lib/mongo_mapper/plugins/logger.rb +2 -0
  43. data/lib/mongo_mapper/plugins/modifiers.rb +3 -1
  44. data/lib/mongo_mapper/plugins/pagination.rb +2 -0
  45. data/lib/mongo_mapper/plugins/persistence.rb +2 -0
  46. data/lib/mongo_mapper/plugins/protected.rb +2 -0
  47. data/lib/mongo_mapper/plugins/querying.rb +5 -4
  48. data/lib/mongo_mapper/plugins/rails.rb +3 -5
  49. data/lib/mongo_mapper/plugins/safe.rb +2 -0
  50. data/lib/mongo_mapper/plugins/sci.rb +2 -0
  51. data/lib/mongo_mapper/plugins/scopes.rb +2 -0
  52. data/lib/mongo_mapper/plugins/serialization.rb +67 -46
  53. data/lib/mongo_mapper/plugins/timestamps.rb +3 -1
  54. data/lib/mongo_mapper/plugins/userstamps.rb +2 -0
  55. data/lib/mongo_mapper/plugins/validations.rb +40 -24
  56. data/lib/mongo_mapper/railtie.rb +49 -0
  57. data/lib/mongo_mapper/railtie/database.rake +60 -0
  58. data/lib/mongo_mapper/support/descendant_appends.rb +11 -11
  59. data/lib/mongo_mapper/translation.rb +10 -0
  60. data/lib/mongo_mapper/version.rb +1 -1
  61. data/lib/rails/generators/mongo_mapper/config/config_generator.rb +24 -0
  62. data/lib/rails/generators/mongo_mapper/config/templates/mongo.yml +18 -0
  63. data/lib/rails/generators/mongo_mapper/model/model_generator.rb +23 -0
  64. data/lib/rails/generators/mongo_mapper/model/templates/model.rb +11 -0
  65. data/test/functional/associations/test_belongs_to_polymorphic_proxy.rb +1 -0
  66. data/test/functional/associations/test_belongs_to_proxy.rb +131 -1
  67. data/test/functional/associations/test_in_array_proxy.rb +30 -0
  68. data/test/functional/associations/test_many_documents_proxy.rb +30 -2
  69. data/test/functional/associations/test_many_embedded_proxy.rb +33 -0
  70. data/test/functional/associations/test_many_polymorphic_proxy.rb +1 -0
  71. data/test/functional/associations/test_one_embedded_proxy.rb +21 -2
  72. data/test/functional/associations/test_one_proxy.rb +49 -9
  73. data/test/functional/test_associations.rb +2 -0
  74. data/test/functional/test_caching.rb +3 -2
  75. data/test/functional/test_callbacks.rb +25 -18
  76. data/test/functional/test_dirty.rb +123 -1
  77. data/test/functional/test_document.rb +26 -2
  78. data/test/functional/test_embedded_document.rb +68 -2
  79. data/test/functional/test_identity_map.rb +3 -4
  80. data/test/functional/test_querying.rb +11 -0
  81. data/test/functional/test_userstamps.rb +2 -2
  82. data/test/functional/test_validations.rb +31 -29
  83. data/test/models.rb +10 -0
  84. data/test/test_active_model_lint.rb +1 -1
  85. data/test/test_helper.rb +9 -10
  86. data/test/unit/associations/test_base.rb +24 -100
  87. data/test/unit/associations/test_belongs_to_association.rb +29 -0
  88. data/test/unit/associations/test_many_association.rb +63 -0
  89. data/test/unit/associations/test_one_association.rb +18 -0
  90. data/test/unit/serializers/test_json_serializer.rb +0 -1
  91. data/test/unit/test_descendant_appends.rb +8 -16
  92. data/test/unit/test_document.rb +4 -9
  93. data/test/unit/test_dynamic_finder.rb +1 -1
  94. data/test/unit/test_embedded_document.rb +51 -18
  95. data/test/unit/test_identity_map_middleware.rb +34 -0
  96. data/test/unit/test_inspect.rb +22 -0
  97. data/test/unit/test_key.rb +21 -1
  98. data/test/unit/test_keys.rb +0 -2
  99. data/test/unit/test_plugins.rb +106 -20
  100. data/test/unit/test_rails.rb +8 -8
  101. data/test/unit/test_serialization.rb +116 -1
  102. data/test/unit/test_translation.rb +27 -0
  103. data/test/unit/test_validations.rb +66 -81
  104. metadata +103 -43
  105. data/examples/identity_map/middleware.rb +0 -14
  106. data/lib/mongo_mapper/plugins/descendants.rb +0 -17
  107. data/rails/init.rb +0 -19
data/UPGRADES CHANGED
@@ -1,3 +1,13 @@
1
+ 0.8.6 => 0.9
2
+ * [attribute]_before_typecast should become [attribute]_before_type_cast (note the extra _)
3
+ * Change validates_exclusion_of :within option to :in
4
+ * Change validates_inclusion_of :within option to :in
5
+ * descendants now returns all descendants use direct_descendants for just children
6
+ * Switch validate_on_create and validate_on_update use validate :on => :create syntax
7
+ * Added #update_attribute
8
+ * belongs_to and one associations now return a true nil instead of a proxy to nil, so you must now call .build_thing instead of thing.build.
9
+ * Plugins should now extend ActiveSupport::Concern
10
+
1
11
  0.7.6 => 0.8
2
12
  * Proxy#owner has been removed in favor of Proxy#proxy_owner
3
13
  * @new instance variable renamed to @_new (you shouldn't be using this anyway)
data/bin/mmconsole CHANGED
@@ -16,7 +16,6 @@ IRB.conf[:MAIN_CONTEXT] = irb.context
16
16
 
17
17
  irb.context.evaluate("require 'irb/completion'", 0)
18
18
  irb.context.evaluate(%@
19
- include MongoMapper
20
19
 
21
20
  MongoMapper.database = "mm-test"
22
21
  $db = MongoMapper.database
@@ -1,8 +1,2 @@
1
1
  # Using the following will turn on identity map for all models
2
- module IdentityMapAddition
3
- def self.included(model)
4
- model.plugin MongoMapper::Plugins::IdentityMap
5
- end
6
- end
7
-
8
- MongoMapper::Document.append_inclusions(IdentityMapAddition)
2
+ MongoMapper::Document.plugin(MongoMapper::Plugins::IdentityMap)
data/examples/plugins.rb CHANGED
@@ -4,9 +4,11 @@ require 'pp'
4
4
 
5
5
  MongoMapper.database = 'testing'
6
6
 
7
- # To create your own plugin, just create a module.
7
+ # To create your own plugin, just create a module that
8
+ # extends ActiveSupport::Concern.
8
9
  module FooPlugin
9
-
10
+ extend ActiveSupport::Concern
11
+
10
12
  # ClassMethods module will automatically get extended
11
13
  module ClassMethods
12
14
  def foo
@@ -21,14 +23,12 @@ module FooPlugin
21
23
  end
22
24
  end
23
25
 
24
- # If present, configure method will be called and passed the
25
- # model as an argument. Feel free to class_eval or add keys.
26
- # if method is not present, it doesn't call it.
27
- def self.configure(model)
28
- puts "Configuring #{model}..."
29
- model.key :foo, String
26
+ # Any configuration can be done in the #included block, which gets
27
+ # class evaled. Feel free to add keys, validations, or anything else.
28
+ included do
29
+ puts "Configuring #{self}..."
30
+ key :foo, String
30
31
  end
31
-
32
32
  end
33
33
 
34
34
  class User
data/examples/safe.rb ADDED
@@ -0,0 +1,43 @@
1
+ $LOAD_PATH.unshift(File.expand_path('../../lib', __FILE__))
2
+ require 'mongo_mapper'
3
+ MongoMapper.database = 'testing'
4
+
5
+ class User
6
+ include MongoMapper::Document
7
+ key :email, String
8
+ end
9
+
10
+ # Drop collection and ensure unique index on email
11
+ User.collection.drop
12
+ User.ensure_index(:email, :unique => true)
13
+
14
+ User.create(:email => 'nunemaker@gmail.com')
15
+ User.create(:email => 'nunemaker@gmail.com')
16
+
17
+ puts "Count should only be one since the second create failed, count is: #{User.count}" # 1 because second was not created, but no exception raised
18
+ puts
19
+
20
+ # save method also takes options, including :safe
21
+ # which will force raise when duplicate is hit
22
+ begin
23
+ user = User.new(:email => 'nunemaker@gmail.com')
24
+ user.save(:safe => true)
25
+ rescue Mongo::OperationFailure => e
26
+ puts 'Mongo Operation failure raised because duplicate email was entered'
27
+ puts e.inspect
28
+ puts
29
+ end
30
+
31
+ # Mark user model as safe, same as doing this...
32
+ # class User
33
+ # include MongoMapper::Document
34
+ # safe
35
+ # end
36
+ User.safe
37
+
38
+ begin
39
+ User.create(:email => 'nunemaker@gmail.com')
40
+ rescue Mongo::OperationFailure => e
41
+ puts 'Mongo Operation failure raised because duplicate email was entered'
42
+ puts e.inspect
43
+ end
data/lib/mongo_mapper.rb CHANGED
@@ -1,8 +1,10 @@
1
1
  # encoding: UTF-8
2
- # Make sure you have the correct versions of the gems (see gemspec) in your load path.
3
2
  require 'plucky'
4
- require 'validatable'
5
- require 'active_support/all'
3
+ require 'active_support/core_ext'
4
+ require 'active_model'
5
+ require "mongo_mapper/railtie" if defined?(Rails)
6
+
7
+ I18n.load_path << File.expand_path('../mongo_mapper/locale/en.yml', __FILE__)
6
8
 
7
9
  module MongoMapper
8
10
  autoload :Connection, 'mongo_mapper/connection'
@@ -16,43 +18,52 @@ module MongoMapper
16
18
  autoload :Document, 'mongo_mapper/document'
17
19
  autoload :EmbeddedDocument, 'mongo_mapper/embedded_document'
18
20
  autoload :Plugins, 'mongo_mapper/plugins'
21
+ autoload :Translation, 'mongo_mapper/translation'
19
22
  autoload :Version, 'mongo_mapper/version'
20
23
 
24
+ module Middleware
25
+ autoload :IdentityMap, 'mongo_mapper/middleware/identity_map'
26
+ end
27
+
21
28
  module Plugins
22
- autoload :Associations, 'mongo_mapper/plugins/associations'
23
- autoload :Accessible, 'mongo_mapper/plugins/accessible'
24
- autoload :Callbacks, 'mongo_mapper/plugins/callbacks'
25
- autoload :Caching, 'mongo_mapper/plugins/caching'
26
- autoload :Clone, 'mongo_mapper/plugins/clone'
27
- autoload :Descendants, 'mongo_mapper/plugins/descendants'
28
- autoload :Dirty, 'mongo_mapper/plugins/dirty'
29
- autoload :Document, 'mongo_mapper/plugins/document'
30
- autoload :DynamicQuerying, 'mongo_mapper/plugins/dynamic_querying'
31
- autoload :EmbeddedDocument, 'mongo_mapper/plugins/embedded_document'
32
- autoload :Equality, 'mongo_mapper/plugins/equality'
33
- autoload :IdentityMap, 'mongo_mapper/plugins/identity_map'
34
- autoload :Inspect, 'mongo_mapper/plugins/inspect'
35
- autoload :Indexes, 'mongo_mapper/plugins/indexes'
36
- autoload :Keys, 'mongo_mapper/plugins/keys'
37
- autoload :Logger, 'mongo_mapper/plugins/logger'
38
- autoload :Modifiers, 'mongo_mapper/plugins/modifiers'
39
- autoload :Pagination, 'mongo_mapper/plugins/pagination'
40
- autoload :Persistence, 'mongo_mapper/plugins/persistence'
41
- autoload :Protected, 'mongo_mapper/plugins/protected'
42
- autoload :Querying, 'mongo_mapper/plugins/querying'
43
- autoload :Rails, 'mongo_mapper/plugins/rails'
44
- autoload :Safe, 'mongo_mapper/plugins/safe'
45
- autoload :Sci, 'mongo_mapper/plugins/sci'
46
- autoload :Scopes, 'mongo_mapper/plugins/scopes'
47
- autoload :Serialization, 'mongo_mapper/plugins/serialization'
48
- autoload :Timestamps, 'mongo_mapper/plugins/timestamps'
49
- autoload :Userstamps, 'mongo_mapper/plugins/userstamps'
50
- autoload :Validations, 'mongo_mapper/plugins/validations'
29
+ autoload :ActiveModel, 'mongo_mapper/plugins/active_model'
30
+ autoload :Associations, 'mongo_mapper/plugins/associations'
31
+ autoload :Accessible, 'mongo_mapper/plugins/accessible'
32
+ autoload :Callbacks, 'mongo_mapper/plugins/callbacks'
33
+ autoload :Caching, 'mongo_mapper/plugins/caching'
34
+ autoload :Clone, 'mongo_mapper/plugins/clone'
35
+ autoload :Dirty, 'mongo_mapper/plugins/dirty'
36
+ autoload :Document, 'mongo_mapper/plugins/document'
37
+ autoload :DynamicQuerying, 'mongo_mapper/plugins/dynamic_querying'
38
+ autoload :EmbeddedCallbacks, 'mongo_mapper/plugins/embedded_callbacks'
39
+ autoload :EmbeddedDocument, 'mongo_mapper/plugins/embedded_document'
40
+ autoload :Equality, 'mongo_mapper/plugins/equality'
41
+ autoload :IdentityMap, 'mongo_mapper/plugins/identity_map'
42
+ autoload :Inspect, 'mongo_mapper/plugins/inspect'
43
+ autoload :Indexes, 'mongo_mapper/plugins/indexes'
44
+ autoload :Keys, 'mongo_mapper/plugins/keys'
45
+ autoload :Logger, 'mongo_mapper/plugins/logger'
46
+ autoload :Modifiers, 'mongo_mapper/plugins/modifiers'
47
+ autoload :Pagination, 'mongo_mapper/plugins/pagination'
48
+ autoload :Persistence, 'mongo_mapper/plugins/persistence'
49
+ autoload :Protected, 'mongo_mapper/plugins/protected'
50
+ autoload :Querying, 'mongo_mapper/plugins/querying'
51
+ autoload :Rails, 'mongo_mapper/plugins/rails'
52
+ autoload :Safe, 'mongo_mapper/plugins/safe'
53
+ autoload :Sci, 'mongo_mapper/plugins/sci'
54
+ autoload :Scopes, 'mongo_mapper/plugins/scopes'
55
+ autoload :Serialization, 'mongo_mapper/plugins/serialization'
56
+ autoload :Timestamps, 'mongo_mapper/plugins/timestamps'
57
+ autoload :Userstamps, 'mongo_mapper/plugins/userstamps'
58
+ autoload :Validations, 'mongo_mapper/plugins/validations'
51
59
 
52
60
  module Associations
53
61
  autoload :Base, 'mongo_mapper/plugins/associations/base'
54
62
  autoload :Collection, 'mongo_mapper/plugins/associations/collection'
55
63
  autoload :EmbeddedCollection, 'mongo_mapper/plugins/associations/embedded_collection'
64
+ autoload :ManyAssociation, 'mongo_mapper/plugins/associations/many_association'
65
+ autoload :BelongsToAssociation, 'mongo_mapper/plugins/associations/belongs_to_association'
66
+ autoload :OneAssociation, 'mongo_mapper/plugins/associations/one_association'
56
67
  autoload :ManyDocumentsProxy, 'mongo_mapper/plugins/associations/many_documents_proxy'
57
68
  autoload :BelongsToProxy, 'mongo_mapper/plugins/associations/belongs_to_proxy'
58
69
  autoload :BelongsToPolymorphicProxy, 'mongo_mapper/plugins/associations/belongs_to_polymorphic_proxy'
@@ -76,4 +87,6 @@ end
76
87
  require 'mongo_mapper/support/descendant_appends'
77
88
 
78
89
  # FIXME: autoload with proxy is failing, need to investigate
79
- require 'mongo_mapper/plugins/associations/proxy'
90
+ require 'mongo_mapper/plugins/associations/proxy'
91
+
92
+ ActiveSupport.run_load_hooks(:mongo_mapper, MongoMapper)
@@ -1,41 +1,42 @@
1
1
  # encoding: UTF-8
2
2
  module MongoMapper
3
3
  module Document
4
+ extend ActiveSupport::Concern
5
+ extend Plugins
4
6
  extend Support::DescendantAppends
5
7
 
6
- def self.included(model)
7
- model.class_eval do
8
- extend Plugins
8
+ include Plugins::ActiveModel
9
+ include Plugins::Document
10
+ include Plugins::Querying # for now needs to be before associations (save_to_collection)
11
+ include Plugins::Associations
12
+ include Plugins::Caching
13
+ include Plugins::Clone
14
+ include Plugins::DynamicQuerying
15
+ include Plugins::Equality
16
+ include Plugins::Inspect
17
+ include Plugins::Indexes
18
+ include Plugins::Keys
19
+ include Plugins::Dirty # for now dirty needs to be after keys
20
+ include Plugins::Logger
21
+ include Plugins::Modifiers
22
+ include Plugins::Pagination
23
+ include Plugins::Persistence
24
+ include Plugins::Accessible
25
+ include Plugins::Protected
26
+ include Plugins::Rails
27
+ include Plugins::Safe # needs to be after querying (save_to_collection)
28
+ include Plugins::Sci
29
+ include Plugins::Scopes
30
+ include Plugins::Serialization
31
+ include Plugins::Timestamps
32
+ include Plugins::Userstamps
33
+ include Plugins::Validations
34
+ include Plugins::EmbeddedCallbacks
35
+ include Plugins::Callbacks # for now callbacks needs to be after validations
9
36
 
10
- plugin Plugins::Document
11
- plugin Plugins::Querying # for now needs to be before associations (save_to_collection)
12
- plugin Plugins::Associations
13
- plugin Plugins::Caching
14
- plugin Plugins::Clone
15
- plugin Plugins::Descendants
16
- plugin Plugins::DynamicQuerying
17
- plugin Plugins::Equality
18
- plugin Plugins::Inspect
19
- plugin Plugins::Indexes
20
- plugin Plugins::Keys
21
- plugin Plugins::Dirty # for now dirty needs to be after keys
22
- plugin Plugins::Logger
23
- plugin Plugins::Modifiers
24
- plugin Plugins::Pagination
25
- plugin Plugins::Persistence
26
- plugin Plugins::Accessible
27
- plugin Plugins::Protected
28
- plugin Plugins::Rails
29
- plugin Plugins::Safe # needs to be after querying (save_to_collection)
30
- plugin Plugins::Sci
31
- plugin Plugins::Scopes
32
- plugin Plugins::Serialization
33
- plugin Plugins::Timestamps
34
- plugin Plugins::Userstamps
35
- plugin Plugins::Validations
36
- plugin Plugins::Callbacks # for now callbacks needs to be after validations
37
- end
38
- super
37
+ included do
38
+ extend Plugins
39
+ extend Translation
39
40
  end
40
41
  end # Document
41
42
  end # MongoMapper
@@ -2,30 +2,30 @@
2
2
  module MongoMapper
3
3
  module EmbeddedDocument
4
4
  extend Support::DescendantAppends
5
+ extend ActiveSupport::Concern
6
+ extend Plugins
5
7
 
6
- def self.included(model)
7
- model.class_eval do
8
- extend Plugins
8
+ include Plugins::ActiveModel
9
+ include Plugins::EmbeddedDocument
10
+ include Plugins::Associations
11
+ include Plugins::Caching
12
+ include Plugins::Clone
13
+ include Plugins::Equality
14
+ include Plugins::Inspect
15
+ include Plugins::Keys
16
+ include Plugins::Logger
17
+ include Plugins::Persistence
18
+ include Plugins::Accessible
19
+ include Plugins::Protected
20
+ include Plugins::Rails
21
+ include Plugins::Sci
22
+ include Plugins::Serialization
23
+ include Plugins::Validations
24
+ include Plugins::EmbeddedCallbacks
9
25
 
10
- plugin Plugins::EmbeddedDocument
11
- plugin Plugins::Associations
12
- plugin Plugins::Caching
13
- plugin Plugins::Clone
14
- plugin Plugins::Descendants
15
- plugin Plugins::Equality
16
- plugin Plugins::Inspect
17
- plugin Plugins::Keys
18
- plugin Plugins::Logger
19
- plugin Plugins::Persistence
20
- plugin Plugins::Accessible
21
- plugin Plugins::Protected
22
- plugin Plugins::Rails
23
- plugin Plugins::Sci
24
- plugin Plugins::Serialization
25
- plugin Plugins::Validations
26
- plugin Plugins::Callbacks
27
- end
28
- super
26
+ included do
27
+ extend Plugins
28
+ extend Translation
29
29
  end
30
30
  end
31
31
  end
@@ -0,0 +1,5 @@
1
+ en:
2
+ mongo_mapper:
3
+ errors:
4
+ messages:
5
+ taken: "has already been taken"
@@ -0,0 +1,16 @@
1
+ module MongoMapper
2
+ module Middleware
3
+ class IdentityMap
4
+ def initialize(app)
5
+ @app = app
6
+ end
7
+
8
+ def call(env)
9
+ MongoMapper::Plugins::IdentityMap.clear
10
+ @app.call(env)
11
+ ensure
12
+ MongoMapper::Plugins::IdentityMap.clear
13
+ end
14
+ end
15
+ end
16
+ end
@@ -1,15 +1,28 @@
1
1
  # encoding: UTF-8
2
2
  module MongoMapper
3
3
  module Plugins
4
+ include ActiveSupport::DescendantsTracker
5
+
4
6
  def plugins
5
7
  @plugins ||= []
6
8
  end
7
9
 
8
10
  def plugin(mod)
9
- extend mod::ClassMethods if mod.const_defined?(:ClassMethods)
10
- include mod::InstanceMethods if mod.const_defined?(:InstanceMethods)
11
- mod.configure(self) if mod.respond_to?(:configure)
11
+ if ActiveSupport::Concern === mod
12
+ include mod
13
+ else
14
+ warn "[DEPRECATED] Plugins must extend ActiveSupport::Concern"
15
+ extend mod::ClassMethods if mod.const_defined?(:ClassMethods)
16
+ include mod::InstanceMethods if mod.const_defined?(:InstanceMethods)
17
+ mod.configure(self) if mod.respond_to?(:configure)
18
+ end
19
+ direct_descendants.each {|model| model.send(:include, mod) }
12
20
  plugins << mod
13
21
  end
22
+
23
+ def included(base = nil, &block)
24
+ direct_descendants << base if base
25
+ super
26
+ end
14
27
  end
15
28
  end
@@ -1,6 +1,8 @@
1
1
  module MongoMapper
2
2
  module Plugins
3
3
  module Accessible
4
+ extend ActiveSupport::Concern
5
+
4
6
  module ClassMethods
5
7
  def attr_accessible(*attrs)
6
8
  raise AccessibleOrProtected.new(name) if try(:protected_attributes?)
@@ -0,0 +1,18 @@
1
+ # encoding: UTF-8
2
+ module MongoMapper
3
+ module Plugins
4
+ module ActiveModel
5
+ extend ActiveSupport::Concern
6
+
7
+ include ::ActiveModel::Naming
8
+ include ::ActiveModel::Conversion
9
+ include ::ActiveModel::Serialization
10
+ include ::ActiveModel::Serializers::Xml
11
+ include ::ActiveModel::Serializers::JSON
12
+
13
+ included do
14
+ extend ::ActiveModel::Translation
15
+ end
16
+ end
17
+ end
18
+ end
@@ -2,6 +2,8 @@
2
2
  module MongoMapper
3
3
  module Plugins
4
4
  module Associations
5
+ extend ActiveSupport::Concern
6
+
5
7
  module ClassMethods
6
8
  def inherited(subclass)
7
9
  subclass.associations = associations.dup
@@ -9,57 +11,48 @@ module MongoMapper
9
11
  end
10
12
 
11
13
  def belongs_to(association_id, options={}, &extension)
12
- create_association(:belongs_to, association_id, options, &extension)
14
+ create_association(BelongsToAssociation.new(association_id, options, &extension))
13
15
  end
14
16
 
15
17
  def many(association_id, options={}, &extension)
16
- create_association(:many, association_id, options, &extension)
18
+ create_association(ManyAssociation.new(association_id, options, &extension))
17
19
  end
18
20
 
19
21
  def one(association_id, options={}, &extension)
20
- create_association(:one, association_id, options, &extension)
22
+ create_association(OneAssociation.new(association_id, options, &extension))
21
23
  end
22
24
 
23
25
  def associations
24
- @associations ||= HashWithIndifferentAccess.new
26
+ @associations ||= {}
25
27
  end
26
28
 
27
29
  def associations=(hash)
28
30
  @associations = hash
29
31
  end
30
32
 
31
- private
32
- def create_association(type, name, options, &extension)
33
- association = Associations::Base.new(type, name, options, &extension)
34
- associations[association.name] = association
35
-
36
- define_method(association.name) do
37
- get_proxy(association)
38
- end
39
-
40
- define_method("#{association.name}=") do |value|
41
- get_proxy(association).replace(value)
42
- value
43
- end
33
+ def associations_module_defined?
34
+ if method(:const_defined?).arity == 1 # Ruby 1.9 compat check
35
+ const_defined?('MongoMapperAssociations')
36
+ else
37
+ const_defined?('MongoMapperAssociations', false)
38
+ end
39
+ end
44
40
 
45
- if association.one? || association.belongs_to?
46
- define_method("#{association.name}?") do
47
- get_proxy(association).present?
48
- end
41
+ def associations_module
42
+ if associations_module_defined?
43
+ const_get 'MongoMapperAssociations'
44
+ else
45
+ Module.new.tap do |m|
46
+ const_set 'MongoMapperAssociations', m
47
+ include m
49
48
  end
49
+ end
50
+ end
50
51
 
51
- if association.options[:dependent] && association.many? && !association.embeddable?
52
- after_destroy do |doc|
53
- case association.options[:dependent]
54
- when :destroy
55
- doc.get_proxy(association).destroy_all
56
- when :delete_all
57
- doc.get_proxy(association).delete_all
58
- when :nullify
59
- doc.get_proxy(association).nullify
60
- end
61
- end
62
- end
52
+ private
53
+ def create_association(association)
54
+ associations[association.name] = association
55
+ association.setup(self)
63
56
  end
64
57
  end
65
58
 
@@ -69,26 +62,28 @@ module MongoMapper
69
62
  end
70
63
 
71
64
  def embedded_associations
72
- associations.select do |name, association|
73
- association.embeddable?
74
- end.map do |name, association|
75
- association
76
- end
65
+ associations.values.select { |assoc| assoc.embeddable? }
66
+ end
67
+
68
+ def build_proxy(association)
69
+ proxy = association.proxy_class.new(self, association)
70
+ self.instance_variable_set(association.ivar, proxy)
71
+
72
+ proxy
77
73
  end
78
74
 
79
75
  def get_proxy(association)
80
76
  unless proxy = self.instance_variable_get(association.ivar)
81
- proxy = association.proxy_class.new(self, association)
82
- self.instance_variable_set(association.ivar, proxy)
77
+ proxy = build_proxy(association)
83
78
  end
84
79
  proxy
85
80
  end
86
81
 
87
82
  def save_to_collection(options={})
88
- super
83
+ super if defined?(super)
89
84
  associations.each do |association_name, association|
90
85
  proxy = get_proxy(association)
91
- proxy.save_to_collection(options) if proxy.proxy_respond_to?(:save_to_collection)
86
+ proxy.save_to_collection(options) if proxy.proxy_respond_to?(:save_to_collection) && association.autosave?
92
87
  end
93
88
  end
94
89
  end