mark_mapper 0.0.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 (211) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +21 -0
  3. data/README.rdoc +39 -0
  4. data/examples/attr_accessible.rb +24 -0
  5. data/examples/attr_protected.rb +24 -0
  6. data/examples/cache_key.rb +26 -0
  7. data/examples/custom_types.rb +26 -0
  8. data/examples/identity_map.rb +30 -0
  9. data/examples/identity_map/automatic.rb +2 -0
  10. data/examples/keys.rb +42 -0
  11. data/examples/modifiers/set.rb +27 -0
  12. data/examples/plugins.rb +40 -0
  13. data/examples/querying.rb +39 -0
  14. data/examples/sample_app.rb +43 -0
  15. data/examples/scopes.rb +56 -0
  16. data/examples/validating/embedded_docs.rb +31 -0
  17. data/lib/mark_mapper.rb +125 -0
  18. data/lib/mark_mapper/config.rb +90 -0
  19. data/lib/mark_mapper/connection.rb +60 -0
  20. data/lib/mark_mapper/criteria_hash.rb +194 -0
  21. data/lib/mark_mapper/document.rb +46 -0
  22. data/lib/mark_mapper/embedded_document.rb +32 -0
  23. data/lib/mark_mapper/exceptions.rb +33 -0
  24. data/lib/mark_mapper/extensions/array.rb +27 -0
  25. data/lib/mark_mapper/extensions/boolean.rb +45 -0
  26. data/lib/mark_mapper/extensions/date.rb +29 -0
  27. data/lib/mark_mapper/extensions/duplicable.rb +86 -0
  28. data/lib/mark_mapper/extensions/float.rb +18 -0
  29. data/lib/mark_mapper/extensions/hash.rb +26 -0
  30. data/lib/mark_mapper/extensions/integer.rb +27 -0
  31. data/lib/mark_mapper/extensions/kernel.rb +11 -0
  32. data/lib/mark_mapper/extensions/nil_class.rb +18 -0
  33. data/lib/mark_mapper/extensions/object.rb +30 -0
  34. data/lib/mark_mapper/extensions/object_id.rb +18 -0
  35. data/lib/mark_mapper/extensions/set.rb +20 -0
  36. data/lib/mark_mapper/extensions/string.rb +31 -0
  37. data/lib/mark_mapper/extensions/symbol.rb +87 -0
  38. data/lib/mark_mapper/extensions/time.rb +29 -0
  39. data/lib/mark_mapper/locale/en.yml +5 -0
  40. data/lib/mark_mapper/middleware/identity_map.rb +41 -0
  41. data/lib/mark_mapper/normalizers/criteria_hash_key.rb +17 -0
  42. data/lib/mark_mapper/normalizers/criteria_hash_value.rb +66 -0
  43. data/lib/mark_mapper/normalizers/fields_value.rb +26 -0
  44. data/lib/mark_mapper/normalizers/hash_key.rb +19 -0
  45. data/lib/mark_mapper/normalizers/integer.rb +19 -0
  46. data/lib/mark_mapper/normalizers/options_hash_value.rb +83 -0
  47. data/lib/mark_mapper/normalizers/sort_value.rb +55 -0
  48. data/lib/mark_mapper/options_hash.rb +103 -0
  49. data/lib/mark_mapper/pagination.rb +6 -0
  50. data/lib/mark_mapper/pagination/collection.rb +32 -0
  51. data/lib/mark_mapper/pagination/paginator.rb +46 -0
  52. data/lib/mark_mapper/plugins.rb +22 -0
  53. data/lib/mark_mapper/plugins/accessible.rb +61 -0
  54. data/lib/mark_mapper/plugins/active_model.rb +18 -0
  55. data/lib/mark_mapper/plugins/associations.rb +96 -0
  56. data/lib/mark_mapper/plugins/associations/base.rb +98 -0
  57. data/lib/mark_mapper/plugins/associations/belongs_to_association.rb +63 -0
  58. data/lib/mark_mapper/plugins/associations/belongs_to_polymorphic_proxy.rb +35 -0
  59. data/lib/mark_mapper/plugins/associations/belongs_to_proxy.rb +52 -0
  60. data/lib/mark_mapper/plugins/associations/collection.rb +29 -0
  61. data/lib/mark_mapper/plugins/associations/embedded_collection.rb +44 -0
  62. data/lib/mark_mapper/plugins/associations/in_array_proxy.rb +133 -0
  63. data/lib/mark_mapper/plugins/associations/many_association.rb +63 -0
  64. data/lib/mark_mapper/plugins/associations/many_documents_as_proxy.rb +28 -0
  65. data/lib/mark_mapper/plugins/associations/many_documents_proxy.rb +142 -0
  66. data/lib/mark_mapper/plugins/associations/many_embedded_polymorphic_proxy.rb +32 -0
  67. data/lib/mark_mapper/plugins/associations/many_embedded_proxy.rb +24 -0
  68. data/lib/mark_mapper/plugins/associations/many_polymorphic_proxy.rb +14 -0
  69. data/lib/mark_mapper/plugins/associations/one_as_proxy.rb +22 -0
  70. data/lib/mark_mapper/plugins/associations/one_association.rb +48 -0
  71. data/lib/mark_mapper/plugins/associations/one_embedded_polymorphic_proxy.rb +30 -0
  72. data/lib/mark_mapper/plugins/associations/one_embedded_proxy.rb +44 -0
  73. data/lib/mark_mapper/plugins/associations/one_proxy.rb +95 -0
  74. data/lib/mark_mapper/plugins/associations/proxy.rb +138 -0
  75. data/lib/mark_mapper/plugins/associations/single_association.rb +46 -0
  76. data/lib/mark_mapper/plugins/caching.rb +21 -0
  77. data/lib/mark_mapper/plugins/callbacks.rb +42 -0
  78. data/lib/mark_mapper/plugins/clone.rb +24 -0
  79. data/lib/mark_mapper/plugins/counter_cache.rb +97 -0
  80. data/lib/mark_mapper/plugins/dirty.rb +61 -0
  81. data/lib/mark_mapper/plugins/document.rb +41 -0
  82. data/lib/mark_mapper/plugins/dumpable.rb +22 -0
  83. data/lib/mark_mapper/plugins/dynamic_querying.rb +45 -0
  84. data/lib/mark_mapper/plugins/dynamic_querying/dynamic_finder.rb +44 -0
  85. data/lib/mark_mapper/plugins/embedded_callbacks.rb +81 -0
  86. data/lib/mark_mapper/plugins/embedded_document.rb +53 -0
  87. data/lib/mark_mapper/plugins/equality.rb +23 -0
  88. data/lib/mark_mapper/plugins/identity_map.rb +144 -0
  89. data/lib/mark_mapper/plugins/indexable.rb +86 -0
  90. data/lib/mark_mapper/plugins/inspect.rb +16 -0
  91. data/lib/mark_mapper/plugins/keys.rb +470 -0
  92. data/lib/mark_mapper/plugins/keys/key.rb +134 -0
  93. data/lib/mark_mapper/plugins/keys/static.rb +45 -0
  94. data/lib/mark_mapper/plugins/logger.rb +18 -0
  95. data/lib/mark_mapper/plugins/modifiers.rb +140 -0
  96. data/lib/mark_mapper/plugins/pagination.rb +16 -0
  97. data/lib/mark_mapper/plugins/partial_updates.rb +77 -0
  98. data/lib/mark_mapper/plugins/persistence.rb +79 -0
  99. data/lib/mark_mapper/plugins/protected.rb +45 -0
  100. data/lib/mark_mapper/plugins/querying.rb +173 -0
  101. data/lib/mark_mapper/plugins/querying/decorated_markmapper_query.rb +75 -0
  102. data/lib/mark_mapper/plugins/rails.rb +79 -0
  103. data/lib/mark_mapper/plugins/rails/active_record_association_adapter.rb +33 -0
  104. data/lib/mark_mapper/plugins/sci.rb +82 -0
  105. data/lib/mark_mapper/plugins/scopes.rb +28 -0
  106. data/lib/mark_mapper/plugins/serialization.rb +109 -0
  107. data/lib/mark_mapper/plugins/timestamps.rb +29 -0
  108. data/lib/mark_mapper/plugins/touch.rb +18 -0
  109. data/lib/mark_mapper/plugins/userstamps.rb +18 -0
  110. data/lib/mark_mapper/plugins/validations.rb +96 -0
  111. data/lib/mark_mapper/query.rb +278 -0
  112. data/lib/mark_mapper/railtie.rb +52 -0
  113. data/lib/mark_mapper/railtie/database.rake +65 -0
  114. data/lib/mark_mapper/translation.rb +10 -0
  115. data/lib/mark_mapper/version.rb +4 -0
  116. data/lib/rails/generators/mark_mapper/config/config_generator.rb +37 -0
  117. data/lib/rails/generators/mark_mapper/config/templates/marklogic.yml +19 -0
  118. data/lib/rails/generators/mark_mapper/model/model_generator.rb +40 -0
  119. data/lib/rails/generators/mark_mapper/model/templates/model.rb +17 -0
  120. data/spec/config/mark_mapper.yml +6 -0
  121. data/spec/examples_spec.rb +25 -0
  122. data/spec/functional/accessible_spec.rb +198 -0
  123. data/spec/functional/associations/belongs_to_polymorphic_proxy_spec.rb +64 -0
  124. data/spec/functional/associations/belongs_to_proxy_spec.rb +255 -0
  125. data/spec/functional/associations/in_array_proxy_spec.rb +349 -0
  126. data/spec/functional/associations/many_documents_as_proxy_spec.rb +230 -0
  127. data/spec/functional/associations/many_documents_proxy_spec.rb +968 -0
  128. data/spec/functional/associations/many_embedded_polymorphic_proxy_spec.rb +238 -0
  129. data/spec/functional/associations/many_embedded_proxy_spec.rb +288 -0
  130. data/spec/functional/associations/many_polymorphic_proxy_spec.rb +302 -0
  131. data/spec/functional/associations/one_as_proxy_spec.rb +489 -0
  132. data/spec/functional/associations/one_embedded_polymorphic_proxy_spec.rb +207 -0
  133. data/spec/functional/associations/one_embedded_proxy_spec.rb +100 -0
  134. data/spec/functional/associations/one_proxy_spec.rb +406 -0
  135. data/spec/functional/associations_spec.rb +48 -0
  136. data/spec/functional/caching_spec.rb +75 -0
  137. data/spec/functional/callbacks_spec.rb +330 -0
  138. data/spec/functional/counter_cache_spec.rb +235 -0
  139. data/spec/functional/dirty_spec.rb +316 -0
  140. data/spec/functional/document_spec.rb +310 -0
  141. data/spec/functional/dumpable_spec.rb +24 -0
  142. data/spec/functional/dynamic_querying_spec.rb +75 -0
  143. data/spec/functional/embedded_document_spec.rb +316 -0
  144. data/spec/functional/equality_spec.rb +20 -0
  145. data/spec/functional/extensions_spec.rb +16 -0
  146. data/spec/functional/identity_map_spec.rb +483 -0
  147. data/spec/functional/keys_spec.rb +339 -0
  148. data/spec/functional/logger_spec.rb +20 -0
  149. data/spec/functional/modifiers_spec.rb +446 -0
  150. data/spec/functional/options_hash_spec.rb +41 -0
  151. data/spec/functional/pagination_spec.rb +89 -0
  152. data/spec/functional/partial_updates_spec.rb +530 -0
  153. data/spec/functional/protected_spec.rb +199 -0
  154. data/spec/functional/querying_spec.rb +984 -0
  155. data/spec/functional/rails_spec.rb +55 -0
  156. data/spec/functional/sci_spec.rb +374 -0
  157. data/spec/functional/scopes_spec.rb +204 -0
  158. data/spec/functional/static_keys_spec.rb +153 -0
  159. data/spec/functional/timestamps_spec.rb +97 -0
  160. data/spec/functional/touch_spec.rb +125 -0
  161. data/spec/functional/userstamps_spec.rb +46 -0
  162. data/spec/functional/validations_spec.rb +416 -0
  163. data/spec/quality_spec.rb +51 -0
  164. data/spec/spec_helper.rb +150 -0
  165. data/spec/support/matchers.rb +15 -0
  166. data/spec/support/models.rb +256 -0
  167. data/spec/symbol_operator_spec.rb +70 -0
  168. data/spec/symbol_spec.rb +9 -0
  169. data/spec/unit/associations/base_spec.rb +146 -0
  170. data/spec/unit/associations/belongs_to_association_spec.rb +30 -0
  171. data/spec/unit/associations/many_association_spec.rb +64 -0
  172. data/spec/unit/associations/one_association_spec.rb +48 -0
  173. data/spec/unit/associations/proxy_spec.rb +103 -0
  174. data/spec/unit/clone_spec.rb +79 -0
  175. data/spec/unit/config_generator_spec.rb +24 -0
  176. data/spec/unit/criteria_hash_spec.rb +218 -0
  177. data/spec/unit/document_spec.rb +251 -0
  178. data/spec/unit/dynamic_finder_spec.rb +125 -0
  179. data/spec/unit/embedded_document_spec.rb +676 -0
  180. data/spec/unit/equality_spec.rb +38 -0
  181. data/spec/unit/exceptions_spec.rb +12 -0
  182. data/spec/unit/extensions_spec.rb +368 -0
  183. data/spec/unit/identity_map_middleware_spec.rb +134 -0
  184. data/spec/unit/inspect_spec.rb +47 -0
  185. data/spec/unit/key_spec.rb +276 -0
  186. data/spec/unit/keys_spec.rb +155 -0
  187. data/spec/unit/mark_mapper_spec.rb +37 -0
  188. data/spec/unit/model_generator_spec.rb +45 -0
  189. data/spec/unit/normalizers/criteria_hash_key_spec.rb +37 -0
  190. data/spec/unit/normalizers/criteria_hash_value_spec.rb +200 -0
  191. data/spec/unit/normalizers/fields_value_spec.rb +45 -0
  192. data/spec/unit/normalizers/hash_key_spec.rb +15 -0
  193. data/spec/unit/normalizers/integer_spec.rb +24 -0
  194. data/spec/unit/normalizers/options_hash_value_spec.rb +99 -0
  195. data/spec/unit/normalizers/sort_value_spec.rb +98 -0
  196. data/spec/unit/options_hash_spec.rb +64 -0
  197. data/spec/unit/pagination/collection_spec.rb +30 -0
  198. data/spec/unit/pagination/paginator_spec.rb +118 -0
  199. data/spec/unit/pagination_spec.rb +11 -0
  200. data/spec/unit/plugins_spec.rb +89 -0
  201. data/spec/unit/query_spec.rb +837 -0
  202. data/spec/unit/rails_compatibility_spec.rb +40 -0
  203. data/spec/unit/rails_reflect_on_association_spec.rb +118 -0
  204. data/spec/unit/rails_spec.rb +188 -0
  205. data/spec/unit/serialization_spec.rb +169 -0
  206. data/spec/unit/serializers/json_serializer_spec.rb +218 -0
  207. data/spec/unit/serializers/xml_serializer_spec.rb +198 -0
  208. data/spec/unit/time_zones_spec.rb +44 -0
  209. data/spec/unit/translation_spec.rb +27 -0
  210. data/spec/unit/validations_spec.rb +588 -0
  211. metadata +307 -0
@@ -0,0 +1,55 @@
1
+ module MarkMapper
2
+ module Normalizers
3
+ class SortValue
4
+
5
+ # Public: Initializes a MarkMapper::Normalizers::SortValue
6
+ #
7
+ # args - The hash of arguments
8
+ # :key_normalizer - What to use to normalize keys, must
9
+ # respond to call.
10
+ #
11
+ def initialize(args = {})
12
+ @key_normalizer = args.fetch(:key_normalizer) {
13
+ raise ArgumentError, "Missing required key :key_normalizer"
14
+ }
15
+ end
16
+
17
+ # Public: Given a value returns it normalized for MarkLogic's sort option
18
+ def call(value)
19
+ case value
20
+ when Array
21
+ if value.size == 1 && value[0].is_a?(String)
22
+ normalized_sort_piece(value[0])
23
+ else
24
+ value.compact.map { |v| normalized_sort_piece(v).flatten }
25
+ end
26
+ else
27
+ normalized_sort_piece(value)
28
+ end
29
+ end
30
+
31
+ # Private
32
+ def normalized_sort_piece(value)
33
+ case value
34
+ when SymbolOperator
35
+ [normalized_direction(value.field, value.operator)]
36
+ when String
37
+ value.split(',').map do |piece|
38
+ normalized_direction(*piece.split(' '))
39
+ end
40
+ when Symbol
41
+ [normalized_direction(value)]
42
+ else
43
+ value
44
+ end
45
+ end
46
+
47
+ # Private
48
+ def normalized_direction(field, direction=nil)
49
+ direction ||= 'ASC'
50
+ direction = direction.upcase == 'ASC' ? 1 : -1
51
+ [@key_normalizer.call(field).to_s, direction]
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,103 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'mark_mapper/normalizers/hash_key'
4
+ require 'mark_mapper/normalizers/options_hash_value'
5
+
6
+ module MarkMapper
7
+ class OptionsHash
8
+
9
+ # Private: The Hash that stores the query options
10
+ attr_reader :source
11
+
12
+ # Private: The Hash that stores instance options
13
+ attr_reader :options
14
+
15
+ # Public
16
+ def initialize(hash={}, options={})
17
+ @source = {}
18
+ @options = options
19
+ hash.each { |key, value| self[key] = value }
20
+ end
21
+
22
+ def initialize_copy(original)
23
+ super
24
+ @source = @source.dup
25
+ @source.each do |key, value|
26
+ self[key] = value.clone if value.duplicable?
27
+ end
28
+ end
29
+
30
+ # Public
31
+ def [](key)
32
+ @source[key]
33
+ end
34
+
35
+ # Public
36
+ def []=(key, value)
37
+ key = normalized_key(key)
38
+ @source[key] = normalized_value(key, value)
39
+ end
40
+
41
+ # Public
42
+ def keys
43
+ @source.keys
44
+ end
45
+
46
+ # Public
47
+ def ==(other)
48
+ @source == other.source
49
+ end
50
+
51
+ # Public
52
+ def to_hash
53
+ @source
54
+ end
55
+
56
+ # Public
57
+ def fields?
58
+ !self[:fields].nil?
59
+ end
60
+
61
+ # Public
62
+ def merge(other)
63
+ self.class.new(to_hash.merge(other.to_hash))
64
+ end
65
+
66
+ # Public
67
+ def merge!(other)
68
+ other.to_hash.each { |key, value| self[key] = value }
69
+ self
70
+ end
71
+
72
+ # Private
73
+ def normalized_key(key)
74
+ key_normalizer.call(key)
75
+ end
76
+
77
+ # Private
78
+ def normalized_value(key, value)
79
+ value_normalizer.call(key, value)
80
+ end
81
+
82
+ # Private
83
+ def key_normalizer
84
+ @key_normalizer ||= @options.fetch(:key_normalizer) {
85
+ Normalizers::HashKey.new({
86
+ :order => :sort,
87
+ :select => :fields,
88
+ :offset => :skip,
89
+ :id => :_id,
90
+ })
91
+ }
92
+ end
93
+
94
+ # Private
95
+ def value_normalizer
96
+ @value_normalizer ||= @options.fetch(:value_normalizer) {
97
+ Normalizers::OptionsHashValue.new({
98
+ :key_normalizer => key_normalizer,
99
+ })
100
+ }
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,6 @@
1
+ require 'mark_mapper/pagination/collection'
2
+ require 'mark_mapper/pagination/paginator'
3
+
4
+ module MarkMapper
5
+ module Pagination; end
6
+ end
@@ -0,0 +1,32 @@
1
+ require 'forwardable'
2
+
3
+ module MarkMapper
4
+ module Pagination
5
+ class Collection < Array
6
+ extend Forwardable
7
+
8
+ def_delegators :@paginator,
9
+ :total_entries, :total_pages,
10
+ :current_page, :per_page,
11
+ :previous_page, :next_page,
12
+ :skip, :limit,
13
+ :offset, :out_of_bounds?
14
+
15
+ def initialize(records, paginator)
16
+ replace records
17
+ @paginator = paginator
18
+ end
19
+
20
+ def method_missing(method, *args)
21
+ @query.send method, *args
22
+ end
23
+
24
+ # Public
25
+ def paginator(p=nil)
26
+ return @paginator if p.nil?
27
+ @paginator = p
28
+ self
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,46 @@
1
+ # encoding: UTF-8
2
+ module MarkMapper
3
+ module Pagination
4
+ class Paginator
5
+ attr_reader :total_entries, :current_page, :per_page
6
+
7
+ # Public
8
+ def initialize(total, page, per_page=nil)
9
+ @total_entries = total.to_i
10
+ @current_page = [page.to_i, 1].max
11
+ @per_page = (per_page || 25).to_i
12
+ end
13
+
14
+ # Public
15
+ def total_pages
16
+ (@total_entries / @per_page.to_f).ceil
17
+ end
18
+
19
+ # Public
20
+ def out_of_bounds?
21
+ @current_page > total_pages
22
+ end
23
+
24
+ # Public
25
+ def previous_page
26
+ @current_page > 1 ? (@current_page - 1) : nil
27
+ end
28
+
29
+ # Public
30
+ def next_page
31
+ @current_page < total_pages ? (@current_page + 1) : nil
32
+ end
33
+
34
+ # Public
35
+ def skip
36
+ (@current_page - 1) * @per_page
37
+ end
38
+
39
+ # Public
40
+ alias :limit :per_page
41
+
42
+ # Public
43
+ alias :offset :skip
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,22 @@
1
+ # encoding: UTF-8
2
+ module MarkMapper
3
+ module Plugins
4
+ include ActiveSupport::DescendantsTracker
5
+
6
+ def plugins
7
+ @plugins ||= []
8
+ end
9
+
10
+ def plugin(mod)
11
+ raise ArgumentError, "Plugins must extend ActiveSupport::Concern" unless ActiveSupport::Concern === mod
12
+ include mod
13
+ direct_descendants.each {|model| model.send(:include, mod) }
14
+ plugins << mod
15
+ end
16
+
17
+ def included(base = nil)
18
+ direct_descendants << base if base
19
+ super
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,61 @@
1
+ module MarkMapper
2
+ module Plugins
3
+ module Accessible
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ class_attribute :_accessible_attributes
8
+ end
9
+
10
+ module ClassMethods
11
+ def attr_accessible(*attrs)
12
+ raise AccessibleOrProtected.new(name) if try(:protected_attributes?)
13
+ self._accessible_attributes = Set.new(attrs) + (_accessible_attributes || [])
14
+ end
15
+
16
+ def accessible_attributes(*)
17
+ _accessible_attributes
18
+ end
19
+
20
+ def accessible_attributes?
21
+ _accessible_attributes?
22
+ end
23
+ end
24
+
25
+ def attributes=(attrs={})
26
+ super(filter_inaccessible_attrs(attrs))
27
+ end
28
+
29
+ def update_attributes(attrs={})
30
+ super(filter_inaccessible_attrs(attrs))
31
+ end
32
+
33
+ def update_attributes!(attrs={})
34
+ super(filter_inaccessible_attrs(attrs))
35
+ end
36
+
37
+ def accessible_attributes(*args)
38
+ self.class.accessible_attributes(*args)
39
+ end
40
+
41
+ def accessible_attributes?
42
+ self.class.accessible_attributes?
43
+ end
44
+
45
+ protected
46
+ def filter_inaccessible_attrs(attrs)
47
+ return attrs if !accessible_attributes? || attrs.blank?
48
+ attrs.dup.delete_if { |key, val| attribute_inaccessible?(key.to_sym) }
49
+ end
50
+
51
+ def attribute_inaccessible?(attribute)
52
+ unless accessible_attributes.include?(attribute)
53
+ message = "Can't mass-assign protected attribute: #{attribute}"
54
+ MarkMapper.logger ? MarkMapper.logger.warn(message) : puts(message)
55
+
56
+ return true
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,18 @@
1
+ # encoding: UTF-8
2
+ module MarkMapper
3
+ module Plugins
4
+ module ActiveModel
5
+ extend ActiveSupport::Concern
6
+
7
+ include ::ActiveModel::Conversion
8
+ include ::ActiveModel::Serialization
9
+ include ::ActiveModel::Serializers::Xml
10
+ include ::ActiveModel::Serializers::JSON
11
+
12
+ included do
13
+ extend ::ActiveModel::Naming
14
+ extend ::ActiveModel::Translation
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,96 @@
1
+ # encoding: UTF-8
2
+ module MarkMapper
3
+ module Plugins
4
+ module Associations
5
+ extend ActiveSupport::Concern
6
+
7
+ module ClassMethods
8
+ def inherited(subclass)
9
+ subclass.associations = associations.dup
10
+ super
11
+ end
12
+
13
+ def belongs_to(association_id, options={}, &extension)
14
+ create_association(BelongsToAssociation.new(association_id, options, &extension))
15
+ end
16
+
17
+ def many(association_id, options={}, &extension)
18
+ create_association(ManyAssociation.new(association_id, options, &extension))
19
+ end
20
+
21
+ def one(association_id, options={}, &extension)
22
+ create_association(OneAssociation.new(association_id, options, &extension))
23
+ end
24
+
25
+ def associations
26
+ @associations ||= {}
27
+ end
28
+
29
+ def associations=(hash)
30
+ @embedded_associations = nil
31
+ @associations = hash
32
+ end
33
+
34
+ def embedded_associations
35
+ @embedded_associations ||= associations.values.select { |assoc| assoc.embeddable? }
36
+ end
37
+
38
+ def associations_module_defined?
39
+ # :nocov:
40
+ if method(:const_defined?).arity == 1 # Ruby 1.9 compat check
41
+ const_defined?('MarkMapperAssociations')
42
+ else
43
+ const_defined?('MarkMapperAssociations', false)
44
+ end
45
+ # :nocov:
46
+ end
47
+
48
+ def associations_module
49
+ if associations_module_defined?
50
+ const_get 'MarkMapperAssociations'
51
+ else
52
+ Module.new.tap do |m|
53
+ const_set 'MarkMapperAssociations', m
54
+ include m
55
+ end
56
+ end
57
+ end
58
+
59
+ private
60
+ def create_association(association)
61
+ @embedded_associations = nil
62
+ associations[association.name] = association
63
+ association.setup(self)
64
+ end
65
+ end
66
+
67
+ def associations
68
+ self.class.associations
69
+ end
70
+
71
+ def embedded_associations
72
+ self.class.embedded_associations
73
+ end
74
+
75
+ def build_proxy(association)
76
+ proxy = association.proxy_class.new(self, association)
77
+ self.instance_variable_set(association.ivar, proxy)
78
+
79
+ proxy
80
+ end
81
+
82
+ def get_proxy(association)
83
+ proxy = self.instance_variable_get(association.ivar) if instance_variable_defined?(association.ivar)
84
+ proxy ||= build_proxy(association)
85
+ end
86
+
87
+ def save_to_collection(options={})
88
+ super if defined?(super)
89
+ associations.each do |association_name, association|
90
+ proxy = get_proxy(association)
91
+ proxy.save_to_collection(options) if proxy.proxy_respond_to?(:save_to_collection) && association.autosave?
92
+ end
93
+ end
94
+ end
95
+ end
96
+ end