mongoid-braxton 2.0.2

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 (226) hide show
  1. data/LICENSE +20 -0
  2. data/README.rdoc +50 -0
  3. data/Rakefile +51 -0
  4. data/lib/config/locales/bg.yml +41 -0
  5. data/lib/config/locales/de.yml +41 -0
  6. data/lib/config/locales/en.yml +45 -0
  7. data/lib/config/locales/es.yml +41 -0
  8. data/lib/config/locales/fr.yml +42 -0
  9. data/lib/config/locales/hu.yml +44 -0
  10. data/lib/config/locales/id.yml +46 -0
  11. data/lib/config/locales/it.yml +39 -0
  12. data/lib/config/locales/ja.yml +40 -0
  13. data/lib/config/locales/kr.yml +65 -0
  14. data/lib/config/locales/nl.yml +39 -0
  15. data/lib/config/locales/pl.yml +39 -0
  16. data/lib/config/locales/pt-BR.yml +40 -0
  17. data/lib/config/locales/pt.yml +40 -0
  18. data/lib/config/locales/ro.yml +46 -0
  19. data/lib/config/locales/ru.yml +41 -0
  20. data/lib/config/locales/sv.yml +40 -0
  21. data/lib/config/locales/vi.yml +45 -0
  22. data/lib/config/locales/zh-CN.yml +33 -0
  23. data/lib/mongoid.rb +140 -0
  24. data/lib/mongoid/atomicity.rb +111 -0
  25. data/lib/mongoid/attributes.rb +185 -0
  26. data/lib/mongoid/attributes/processing.rb +145 -0
  27. data/lib/mongoid/callbacks.rb +23 -0
  28. data/lib/mongoid/collection.rb +137 -0
  29. data/lib/mongoid/collections.rb +71 -0
  30. data/lib/mongoid/collections/master.rb +37 -0
  31. data/lib/mongoid/collections/operations.rb +42 -0
  32. data/lib/mongoid/collections/retry.rb +39 -0
  33. data/lib/mongoid/components.rb +45 -0
  34. data/lib/mongoid/config.rb +349 -0
  35. data/lib/mongoid/config/database.rb +167 -0
  36. data/lib/mongoid/config/replset_database.rb +78 -0
  37. data/lib/mongoid/contexts.rb +19 -0
  38. data/lib/mongoid/contexts/enumerable.rb +275 -0
  39. data/lib/mongoid/contexts/enumerable/sort.rb +43 -0
  40. data/lib/mongoid/contexts/mongo.rb +345 -0
  41. data/lib/mongoid/copyable.rb +46 -0
  42. data/lib/mongoid/criteria.rb +357 -0
  43. data/lib/mongoid/criterion/builder.rb +34 -0
  44. data/lib/mongoid/criterion/complex.rb +34 -0
  45. data/lib/mongoid/criterion/creational.rb +34 -0
  46. data/lib/mongoid/criterion/exclusion.rb +108 -0
  47. data/lib/mongoid/criterion/inclusion.rb +198 -0
  48. data/lib/mongoid/criterion/inspection.rb +22 -0
  49. data/lib/mongoid/criterion/optional.rb +193 -0
  50. data/lib/mongoid/criterion/selector.rb +143 -0
  51. data/lib/mongoid/criterion/unconvertable.rb +20 -0
  52. data/lib/mongoid/cursor.rb +86 -0
  53. data/lib/mongoid/default_scope.rb +36 -0
  54. data/lib/mongoid/dirty.rb +253 -0
  55. data/lib/mongoid/document.rb +284 -0
  56. data/lib/mongoid/errors.rb +13 -0
  57. data/lib/mongoid/errors/document_not_found.rb +29 -0
  58. data/lib/mongoid/errors/invalid_collection.rb +19 -0
  59. data/lib/mongoid/errors/invalid_database.rb +20 -0
  60. data/lib/mongoid/errors/invalid_field.rb +19 -0
  61. data/lib/mongoid/errors/invalid_options.rb +16 -0
  62. data/lib/mongoid/errors/invalid_type.rb +26 -0
  63. data/lib/mongoid/errors/mixed_relations.rb +37 -0
  64. data/lib/mongoid/errors/mongoid_error.rb +27 -0
  65. data/lib/mongoid/errors/too_many_nested_attribute_records.rb +21 -0
  66. data/lib/mongoid/errors/unsaved_document.rb +23 -0
  67. data/lib/mongoid/errors/unsupported_version.rb +21 -0
  68. data/lib/mongoid/errors/validations.rb +24 -0
  69. data/lib/mongoid/extensions.rb +123 -0
  70. data/lib/mongoid/extensions/array/conversions.rb +23 -0
  71. data/lib/mongoid/extensions/array/parentization.rb +13 -0
  72. data/lib/mongoid/extensions/big_decimal/conversions.rb +19 -0
  73. data/lib/mongoid/extensions/binary/conversions.rb +17 -0
  74. data/lib/mongoid/extensions/boolean/conversions.rb +27 -0
  75. data/lib/mongoid/extensions/date/conversions.rb +25 -0
  76. data/lib/mongoid/extensions/datetime/conversions.rb +12 -0
  77. data/lib/mongoid/extensions/false_class/equality.rb +13 -0
  78. data/lib/mongoid/extensions/float/conversions.rb +20 -0
  79. data/lib/mongoid/extensions/hash/conversions.rb +19 -0
  80. data/lib/mongoid/extensions/hash/criteria_helpers.rb +22 -0
  81. data/lib/mongoid/extensions/hash/scoping.rb +12 -0
  82. data/lib/mongoid/extensions/integer/conversions.rb +20 -0
  83. data/lib/mongoid/extensions/nil/collectionization.rb +12 -0
  84. data/lib/mongoid/extensions/object/checks.rb +32 -0
  85. data/lib/mongoid/extensions/object/conversions.rb +25 -0
  86. data/lib/mongoid/extensions/object/reflections.rb +17 -0
  87. data/lib/mongoid/extensions/object/yoda.rb +27 -0
  88. data/lib/mongoid/extensions/object_id/conversions.rb +96 -0
  89. data/lib/mongoid/extensions/proc/scoping.rb +12 -0
  90. data/lib/mongoid/extensions/range/conversions.rb +25 -0
  91. data/lib/mongoid/extensions/set/conversions.rb +20 -0
  92. data/lib/mongoid/extensions/string/conversions.rb +34 -0
  93. data/lib/mongoid/extensions/string/inflections.rb +97 -0
  94. data/lib/mongoid/extensions/symbol/conversions.rb +21 -0
  95. data/lib/mongoid/extensions/symbol/inflections.rb +40 -0
  96. data/lib/mongoid/extensions/time_conversions.rb +38 -0
  97. data/lib/mongoid/extensions/true_class/equality.rb +13 -0
  98. data/lib/mongoid/extras.rb +42 -0
  99. data/lib/mongoid/factory.rb +37 -0
  100. data/lib/mongoid/field.rb +162 -0
  101. data/lib/mongoid/fields.rb +183 -0
  102. data/lib/mongoid/finders.rb +127 -0
  103. data/lib/mongoid/hierarchy.rb +85 -0
  104. data/lib/mongoid/identity.rb +92 -0
  105. data/lib/mongoid/indexes.rb +38 -0
  106. data/lib/mongoid/inspection.rb +54 -0
  107. data/lib/mongoid/javascript.rb +21 -0
  108. data/lib/mongoid/javascript/functions.yml +37 -0
  109. data/lib/mongoid/json.rb +16 -0
  110. data/lib/mongoid/keys.rb +131 -0
  111. data/lib/mongoid/logger.rb +18 -0
  112. data/lib/mongoid/matchers.rb +32 -0
  113. data/lib/mongoid/matchers/all.rb +11 -0
  114. data/lib/mongoid/matchers/default.rb +70 -0
  115. data/lib/mongoid/matchers/exists.rb +13 -0
  116. data/lib/mongoid/matchers/gt.rb +11 -0
  117. data/lib/mongoid/matchers/gte.rb +11 -0
  118. data/lib/mongoid/matchers/in.rb +11 -0
  119. data/lib/mongoid/matchers/lt.rb +11 -0
  120. data/lib/mongoid/matchers/lte.rb +11 -0
  121. data/lib/mongoid/matchers/ne.rb +11 -0
  122. data/lib/mongoid/matchers/nin.rb +11 -0
  123. data/lib/mongoid/matchers/or.rb +30 -0
  124. data/lib/mongoid/matchers/size.rb +11 -0
  125. data/lib/mongoid/matchers/strategies.rb +63 -0
  126. data/lib/mongoid/multi_database.rb +11 -0
  127. data/lib/mongoid/multi_parameter_attributes.rb +82 -0
  128. data/lib/mongoid/named_scope.rb +137 -0
  129. data/lib/mongoid/nested_attributes.rb +51 -0
  130. data/lib/mongoid/observer.rb +67 -0
  131. data/lib/mongoid/paranoia.rb +103 -0
  132. data/lib/mongoid/paths.rb +61 -0
  133. data/lib/mongoid/persistence.rb +240 -0
  134. data/lib/mongoid/persistence/atomic.rb +88 -0
  135. data/lib/mongoid/persistence/atomic/add_to_set.rb +32 -0
  136. data/lib/mongoid/persistence/atomic/inc.rb +28 -0
  137. data/lib/mongoid/persistence/atomic/operation.rb +44 -0
  138. data/lib/mongoid/persistence/atomic/pull_all.rb +33 -0
  139. data/lib/mongoid/persistence/atomic/push.rb +28 -0
  140. data/lib/mongoid/persistence/command.rb +71 -0
  141. data/lib/mongoid/persistence/insert.rb +53 -0
  142. data/lib/mongoid/persistence/insert_embedded.rb +43 -0
  143. data/lib/mongoid/persistence/remove.rb +44 -0
  144. data/lib/mongoid/persistence/remove_all.rb +40 -0
  145. data/lib/mongoid/persistence/remove_embedded.rb +48 -0
  146. data/lib/mongoid/persistence/update.rb +77 -0
  147. data/lib/mongoid/railtie.rb +139 -0
  148. data/lib/mongoid/railties/database.rake +171 -0
  149. data/lib/mongoid/railties/document.rb +12 -0
  150. data/lib/mongoid/relations.rb +107 -0
  151. data/lib/mongoid/relations/accessors.rb +175 -0
  152. data/lib/mongoid/relations/auto_save.rb +34 -0
  153. data/lib/mongoid/relations/binding.rb +26 -0
  154. data/lib/mongoid/relations/bindings.rb +9 -0
  155. data/lib/mongoid/relations/bindings/embedded/in.rb +82 -0
  156. data/lib/mongoid/relations/bindings/embedded/many.rb +98 -0
  157. data/lib/mongoid/relations/bindings/embedded/one.rb +66 -0
  158. data/lib/mongoid/relations/bindings/referenced/in.rb +74 -0
  159. data/lib/mongoid/relations/bindings/referenced/many.rb +96 -0
  160. data/lib/mongoid/relations/bindings/referenced/many_to_many.rb +103 -0
  161. data/lib/mongoid/relations/bindings/referenced/one.rb +66 -0
  162. data/lib/mongoid/relations/builder.rb +42 -0
  163. data/lib/mongoid/relations/builders.rb +79 -0
  164. data/lib/mongoid/relations/builders/embedded/in.rb +25 -0
  165. data/lib/mongoid/relations/builders/embedded/many.rb +32 -0
  166. data/lib/mongoid/relations/builders/embedded/one.rb +26 -0
  167. data/lib/mongoid/relations/builders/nested_attributes/many.rb +126 -0
  168. data/lib/mongoid/relations/builders/nested_attributes/one.rb +135 -0
  169. data/lib/mongoid/relations/builders/referenced/in.rb +29 -0
  170. data/lib/mongoid/relations/builders/referenced/many.rb +47 -0
  171. data/lib/mongoid/relations/builders/referenced/many_to_many.rb +29 -0
  172. data/lib/mongoid/relations/builders/referenced/one.rb +27 -0
  173. data/lib/mongoid/relations/cascading.rb +55 -0
  174. data/lib/mongoid/relations/cascading/delete.rb +19 -0
  175. data/lib/mongoid/relations/cascading/destroy.rb +19 -0
  176. data/lib/mongoid/relations/cascading/nullify.rb +18 -0
  177. data/lib/mongoid/relations/cascading/strategy.rb +26 -0
  178. data/lib/mongoid/relations/constraint.rb +42 -0
  179. data/lib/mongoid/relations/cyclic.rb +103 -0
  180. data/lib/mongoid/relations/embedded/atomic.rb +86 -0
  181. data/lib/mongoid/relations/embedded/atomic/operation.rb +63 -0
  182. data/lib/mongoid/relations/embedded/atomic/pull.rb +65 -0
  183. data/lib/mongoid/relations/embedded/atomic/push_all.rb +59 -0
  184. data/lib/mongoid/relations/embedded/atomic/set.rb +61 -0
  185. data/lib/mongoid/relations/embedded/atomic/unset.rb +41 -0
  186. data/lib/mongoid/relations/embedded/in.rb +173 -0
  187. data/lib/mongoid/relations/embedded/many.rb +499 -0
  188. data/lib/mongoid/relations/embedded/one.rb +170 -0
  189. data/lib/mongoid/relations/macros.rb +310 -0
  190. data/lib/mongoid/relations/many.rb +215 -0
  191. data/lib/mongoid/relations/metadata.rb +539 -0
  192. data/lib/mongoid/relations/nested_builder.rb +68 -0
  193. data/lib/mongoid/relations/one.rb +47 -0
  194. data/lib/mongoid/relations/polymorphic.rb +54 -0
  195. data/lib/mongoid/relations/proxy.rb +143 -0
  196. data/lib/mongoid/relations/referenced/batch.rb +71 -0
  197. data/lib/mongoid/relations/referenced/batch/insert.rb +57 -0
  198. data/lib/mongoid/relations/referenced/in.rb +216 -0
  199. data/lib/mongoid/relations/referenced/many.rb +516 -0
  200. data/lib/mongoid/relations/referenced/many_to_many.rb +396 -0
  201. data/lib/mongoid/relations/referenced/one.rb +222 -0
  202. data/lib/mongoid/relations/reflections.rb +45 -0
  203. data/lib/mongoid/safe.rb +23 -0
  204. data/lib/mongoid/safety.rb +207 -0
  205. data/lib/mongoid/scope.rb +31 -0
  206. data/lib/mongoid/serialization.rb +99 -0
  207. data/lib/mongoid/sharding.rb +51 -0
  208. data/lib/mongoid/state.rb +67 -0
  209. data/lib/mongoid/timestamps.rb +14 -0
  210. data/lib/mongoid/timestamps/created.rb +31 -0
  211. data/lib/mongoid/timestamps/updated.rb +33 -0
  212. data/lib/mongoid/validations.rb +124 -0
  213. data/lib/mongoid/validations/associated.rb +44 -0
  214. data/lib/mongoid/validations/referenced.rb +58 -0
  215. data/lib/mongoid/validations/uniqueness.rb +85 -0
  216. data/lib/mongoid/version.rb +4 -0
  217. data/lib/mongoid/versioning.rb +113 -0
  218. data/lib/rails/generators/mongoid/config/config_generator.rb +25 -0
  219. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +20 -0
  220. data/lib/rails/generators/mongoid/model/model_generator.rb +24 -0
  221. data/lib/rails/generators/mongoid/model/templates/model.rb +19 -0
  222. data/lib/rails/generators/mongoid/observer/observer_generator.rb +17 -0
  223. data/lib/rails/generators/mongoid/observer/templates/observer.rb +4 -0
  224. data/lib/rails/generators/mongoid_generator.rb +70 -0
  225. data/lib/rails/mongoid.rb +58 -0
  226. metadata +406 -0
@@ -0,0 +1,139 @@
1
+ # encoding: utf-8
2
+ require "singleton"
3
+ require "mongoid"
4
+ require "mongoid/config"
5
+ require "mongoid/railties/document"
6
+ require "rails"
7
+ require "rails/mongoid"
8
+
9
+ module Rails #:nodoc:
10
+ module Mongoid #:nodoc:
11
+ class Railtie < Rails::Railtie #:nodoc:
12
+
13
+ # Determine which generator to use. app_generators was introduced after
14
+ # 3.0.0.
15
+ #
16
+ # @example Get the generators method.
17
+ # railtie.generators
18
+ #
19
+ # @return [ Symbol ] The method name to use.
20
+ #
21
+ # @since 2.0.0.rc.4
22
+ def self.generator
23
+ config.respond_to?(:app_generators) ? :app_generators : :generators
24
+ end
25
+
26
+ config.send(generator).orm :mongoid, :migration => false
27
+
28
+ rake_tasks do
29
+ load "mongoid/railties/database.rake"
30
+ end
31
+
32
+ # Exposes Mongoid's configuration to the Rails application configuration.
33
+ #
34
+ # @example Set up configuration in the Rails app.
35
+ # module MyApplication
36
+ # class Application < Rails::Application
37
+ # config.mongoid.logger = Logger.new($stdout, :warn)
38
+ # config.mongoid.persist_in_safe_mode = true
39
+ # end
40
+ # end
41
+ config.mongoid = ::Mongoid::Config
42
+
43
+ # Initialize Mongoid. This will look for a mongoid.yml in the config
44
+ # directory and configure mongoid appropriately.
45
+ #
46
+ # @example mongoid.yml
47
+ #
48
+ # development:
49
+ # host: localhost
50
+ # database: mongoid
51
+ # slaves:
52
+ # # - host: localhost
53
+ # # port: 27018
54
+ # # - host: localhost
55
+ # # port: 27019
56
+ # allow_dynamic_fields: false
57
+ # parameterize_keys: false
58
+ # persist_in_safe_mode: false
59
+ #
60
+ initializer "setup database" do
61
+ config_file = Rails.root.join("config", "mongoid.yml")
62
+ if config_file.file?
63
+ settings = YAML.load(ERB.new(config_file.read).result)[Rails.env]
64
+ ::Mongoid.from_hash(settings) if settings.present?
65
+ end
66
+ end
67
+
68
+ # After initialization we will warn the user if we can't find a mongoid.yml and
69
+ # alert to create one.
70
+ initializer "warn when configuration is missing" do
71
+ config.after_initialize do
72
+ unless Rails.root.join("config", "mongoid.yml").file?
73
+ puts "\nMongoid config not found. Create a config file at: config/mongoid.yml"
74
+ puts "to generate one run: rails generate mongoid:config\n\n"
75
+ end
76
+ end
77
+ end
78
+
79
+ # Due to all models not getting loaded and messing up inheritance queries
80
+ # and indexing, we need to preload the models in order to address this.
81
+ #
82
+ # This will happen every request in development, once in ther other
83
+ # environments.
84
+ initializer "preload all application models" do |app|
85
+ config.to_prepare do
86
+ ::Rails::Mongoid.load_models(app) unless $rails_rake_task
87
+ end
88
+ end
89
+
90
+ # Set the proper error types for Rails. DocumentNotFound errors should be
91
+ # 404s and not 500s, validation errors are 422s.
92
+ initializer "load http errors" do |app|
93
+ config.after_initialize do
94
+ ActionDispatch::ShowExceptions.rescue_responses.update({
95
+ "Mongoid::Errors::DocumentNotFound" => :not_found,
96
+ "Mongoid::Errors::Validations" => 422
97
+ })
98
+ end
99
+ end
100
+
101
+ # When workers are forked in passenger and unicorn, we need to reconnect
102
+ # to the database to all the workers do not share the same connection.
103
+ initializer "reconnect to master if application is preloaded" do
104
+ config.after_initialize do
105
+
106
+ # Unicorn clears the START_CTX when a worker is forked, so if we have
107
+ # data in START_CTX then we know we're being preloaded. Unicorn does
108
+ # not provide application-level hooks for executing code after the
109
+ # process has forked, so we reconnect lazily.
110
+ if defined?(Unicorn) && !Unicorn::HttpServer::START_CTX.empty?
111
+ ::Mongoid.reconnect!(false)
112
+ end
113
+
114
+ # Passenger provides the :starting_worker_process event for executing
115
+ # code after it has forked, so we use that and reconnect immediately.
116
+ if defined?(PhusionPassenger)
117
+ PhusionPassenger.on_event(:starting_worker_process) do |forked|
118
+ if forked
119
+ ::Mongoid.reconnect!
120
+ end
121
+ end
122
+ end
123
+ end
124
+ end
125
+
126
+ # Instantitate any registered observers after Rails initialization and
127
+ # instantiate them after being reloaded in the development environment
128
+ initializer "instantiate observers" do
129
+ config.after_initialize do
130
+ ::Mongoid.instantiate_observers
131
+
132
+ ActionDispatch::Callbacks.to_prepare do
133
+ ::Mongoid.instantiate_observers
134
+ end
135
+ end
136
+ end
137
+ end
138
+ end
139
+ end
@@ -0,0 +1,171 @@
1
+ namespace :db do
2
+
3
+ if not Rake::Task.task_defined?("db:drop")
4
+ desc 'Drops all the collections for the database for the current Rails.env'
5
+ task :drop => :environment do
6
+ Mongoid.master.collections.select {|c| c.name !~ /system/ }.each(&:drop)
7
+ end
8
+ end
9
+
10
+ if not Rake::Task.task_defined?("db:seed")
11
+ # if another ORM has defined db:seed, don't run it twice.
12
+ desc 'Load the seed data from db/seeds.rb'
13
+ task :seed => :environment do
14
+ seed_file = File.join(Rails.root, 'db', 'seeds.rb')
15
+ load(seed_file) if File.exist?(seed_file)
16
+ end
17
+ end
18
+
19
+ if not Rake::Task.task_defined?("db:setup")
20
+ desc 'Create the database, and initialize with the seed data'
21
+ task :setup => [ 'db:create', 'db:mongoid:create_indexes', 'db:seed' ]
22
+ end
23
+
24
+ if not Rake::Task.task_defined?("db:reseed")
25
+ desc 'Delete data and seed'
26
+ task :reseed => [ 'db:drop', 'db:seed' ]
27
+ end
28
+
29
+ if not Rake::Task.task_defined?("db:create")
30
+ task :create => :environment do
31
+ # noop
32
+ end
33
+ end
34
+
35
+ if not Rake::Task.task_defined?("db:migrate")
36
+ task :migrate => :environment do
37
+ # noop
38
+ end
39
+ end
40
+
41
+ if not Rake::Task.task_defined?("db:schema:load")
42
+ namespace :schema do
43
+ task :load do
44
+ # noop
45
+ end
46
+ end
47
+ end
48
+
49
+ if not Rake::Task.task_defined?("db:test:prepare")
50
+ namespace :test do
51
+ task :prepare do
52
+ # noop
53
+ end
54
+ end
55
+ end
56
+
57
+ if not Rake::Task.task_defined?("db:create_indexes")
58
+ task :create_indexes => "mongoid:create_indexes"
59
+ end
60
+
61
+ namespace :mongoid do
62
+ # gets a list of the mongoid models defined in the app/models directory
63
+ def get_mongoid_models
64
+ documents = []
65
+ Dir.glob("app/models/**/*.rb").sort.each do |file|
66
+ model_path = file[0..-4].split('/')[2..-1]
67
+ begin
68
+ klass = model_path.map(&:classify).join('::').constantize
69
+ if klass.ancestors.include?(Mongoid::Document) && !klass.embedded
70
+ documents << klass
71
+ end
72
+ rescue => e
73
+ # Just for non-mongoid objects that dont have the embedded
74
+ # attribute at the class level.
75
+ end
76
+ end
77
+ documents
78
+ end
79
+
80
+ desc 'Create the indexes defined on your mongoid models'
81
+ task :create_indexes => :environment do
82
+ ::Rails::Mongoid.index_children(get_mongoid_models)
83
+ end
84
+
85
+ def convert_ids(obj)
86
+ if obj.is_a?(String) && obj =~ /^[a-f0-9]{24}$/
87
+ BSON::ObjectId(obj)
88
+ elsif obj.is_a?(Array)
89
+ obj.map do |v|
90
+ convert_ids(v)
91
+ end
92
+ elsif obj.is_a?(Hash)
93
+ obj.each do |k, v|
94
+ obj[k] = convert_ids(v)
95
+ end
96
+ else
97
+ obj
98
+ end
99
+ end
100
+
101
+ def collection_names
102
+ @collection_names ||= get_mongoid_models.map{ |d| d.collection.name }.uniq
103
+ end
104
+
105
+ desc "Convert string objectids in mongo database to ObjectID type"
106
+ task :objectid_convert => :environment do
107
+ collection_names.each do |collection_name|
108
+ puts "Converting #{collection_name} to use ObjectIDs"
109
+
110
+ # get old collection
111
+ collection = Mongoid.master.collection(collection_name)
112
+
113
+ # get new collection (a clean one)
114
+ collection.db["#{collection_name}_new"].drop
115
+ new_collection = collection.db["#{collection_name}_new"]
116
+
117
+ # convert collection documents
118
+ collection.find({}, :timeout => false, :sort => "_id") do |cursor|
119
+ cursor.each do |doc|
120
+ new_doc = convert_ids(doc)
121
+ new_collection.insert(new_doc, :safe => true)
122
+ end
123
+ end
124
+
125
+ puts "Done! Converted collection is in #{new_collection.name}\n\n"
126
+ end
127
+
128
+ # no errors. great! now rename _new to collection_name
129
+ collection_names.each do |collection_name|
130
+ collection = Mongoid.master.collection(collection_name)
131
+ new_collection = collection.db["#{collection_name}_new"]
132
+
133
+ # swap collection to _old
134
+ puts "Moving #{collection.name} to #{collection_name}_old"
135
+ collection.db["#{collection_name}_old"].drop
136
+
137
+ begin
138
+ collection.rename("#{collection_name}_old")
139
+ rescue Exception => e
140
+ puts "Unable to rename database #{collection_name} to #{collection_name}_old"
141
+ puts "reason: #{e.message}\n\n"
142
+ end
143
+
144
+ # swap _new to collection
145
+ puts "Moving #{new_collection.name} to #{collection_name}\n\n"
146
+
147
+ begin
148
+ new_collection.rename(collection_name)
149
+ rescue Exception => e
150
+ puts "Unable to rename database #{new_collection.name} to #{collection_name}"
151
+ puts "reason: #{e.message}\n\n"
152
+ end
153
+ end
154
+
155
+ puts "DONE! Run `rake db:mongoid:cleanup_old_collections` to remove old collections"
156
+ end
157
+
158
+ desc "Clean up old collections backed up by objectid_convert"
159
+ task :cleanup_old_collections => :environment do
160
+ collection_names.each do |collection_name|
161
+ collection = Mongoid.master.collection(collection_name)
162
+ collection.db["#{collection.name}_old"].drop
163
+ end
164
+ end
165
+
166
+ ########
167
+ # TODO: lots more useful db tasks can be added here. stuff like copyDatabase, etc
168
+ ########
169
+ end
170
+
171
+ end
@@ -0,0 +1,12 @@
1
+ module Mongoid
2
+ module Document
3
+ # Used in conjunction with fields_for to build a form element for the
4
+ # destruction of this association. Always returns false because Mongoid
5
+ # only supports immediate deletion of associations.
6
+ #
7
+ # See ActionView::Helpers::FormHelper::fields_for for more info.
8
+ def _destroy
9
+ false
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,107 @@
1
+ # encoding: utf-8
2
+ require "mongoid/relations/accessors"
3
+ require "mongoid/relations/auto_save"
4
+ require "mongoid/relations/cascading"
5
+ require "mongoid/relations/constraint"
6
+ require "mongoid/relations/cyclic"
7
+ require "mongoid/relations/proxy"
8
+ require "mongoid/relations/bindings"
9
+ require "mongoid/relations/builders"
10
+ require "mongoid/relations/many"
11
+ require "mongoid/relations/one"
12
+ require "mongoid/relations/polymorphic"
13
+ require "mongoid/relations/embedded/atomic"
14
+ require "mongoid/relations/embedded/in"
15
+ require "mongoid/relations/embedded/many"
16
+ require "mongoid/relations/embedded/one"
17
+ require "mongoid/relations/referenced/batch"
18
+ require "mongoid/relations/referenced/in"
19
+ require "mongoid/relations/referenced/many"
20
+ require "mongoid/relations/referenced/many_to_many"
21
+ require "mongoid/relations/referenced/one"
22
+ require "mongoid/relations/reflections"
23
+ require "mongoid/relations/metadata"
24
+ require "mongoid/relations/macros"
25
+
26
+ module Mongoid # :nodoc:
27
+
28
+ # All classes and modules under the relations namespace handle the
29
+ # functionality that has to do with embedded and referenced (relational)
30
+ # associations.
31
+ module Relations
32
+ extend ActiveSupport::Concern
33
+ include Accessors
34
+ include AutoSave
35
+ include Cascading
36
+ include Cyclic
37
+ include Builders
38
+ include Macros
39
+ include Polymorphic
40
+ include Reflections
41
+
42
+ included do
43
+ attr_accessor :metadata
44
+ end
45
+
46
+ # Determine if the document itself is embedded in another document via the
47
+ # proper channels. (If it has a parent document.)
48
+ #
49
+ # @example Is the document embedded?
50
+ # address.embedded?
51
+ #
52
+ # @return [ true, false ] True if the document has a parent document.
53
+ #
54
+ # @since 2.0.0.rc.1
55
+ def embedded?
56
+ cyclic ? _parent.present? : self.class.embedded?
57
+ end
58
+
59
+ # Determine if the document is part of an embeds_many relation.
60
+ #
61
+ # @example Is the document in an embeds many?
62
+ # address.embedded_many?
63
+ #
64
+ # @return [ true, false ] True if in an embeds many.
65
+ #
66
+ # @since 2.0.0.rc.1
67
+ def embedded_many?
68
+ metadata && metadata.macro == :embeds_many
69
+ end
70
+
71
+ # Determine if the document is part of an embeds_one relation.
72
+ #
73
+ # @example Is the document in an embeds one?
74
+ # address.embedded_one?
75
+ #
76
+ # @return [ true, false ] True if in an embeds one.
77
+ #
78
+ # @since 2.0.0.rc.1
79
+ def embedded_one?
80
+ metadata && metadata.macro == :embeds_one
81
+ end
82
+
83
+ # Determine if the document is part of an references_many relation.
84
+ #
85
+ # @example Is the document in a references many?
86
+ # post.referenced_many?
87
+ #
88
+ # @return [ true, false ] True if in a references many.
89
+ #
90
+ # @since 2.0.0.rc.1
91
+ def referenced_many?
92
+ metadata && metadata.macro == :references_many
93
+ end
94
+
95
+ # Determine if the document is part of an references_one relation.
96
+ #
97
+ # @example Is the document in a references one?
98
+ # address.referenced_one?
99
+ #
100
+ # @return [ true, false ] True if in a references one.
101
+ #
102
+ # @since 2.0.0.rc.1
103
+ def referenced_one?
104
+ metadata && metadata.macro == :references_one
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,175 @@
1
+ # encoding: utf-8
2
+ module Mongoid # :nodoc:
3
+ module Relations #:nodoc:
4
+
5
+ # This module contains all the behaviour related to accessing relations
6
+ # through the getters and setters, and how to delegate to builders to
7
+ # create new ones.
8
+ module Accessors
9
+ extend ActiveSupport::Concern
10
+
11
+ # Builds the related document and creates the relation unless the
12
+ # document is nil, then sets the relation on this document.
13
+ #
14
+ # @example Build the relation.
15
+ # person.build(:addresses, { :id => 1 }, metadata)
16
+ #
17
+ # @param [ String, Symbol ] name The name of the relation.
18
+ # @param [ Hash, BSON::ObjectId ] object The id or attributes to use.
19
+ # @param [ Metadata ] metadata The relation's metadata.
20
+ # @param [ true, false ] building If we are in a build operation.
21
+ #
22
+ # @return [ Proxy ] The relation.
23
+ #
24
+ # @since 2.0.0.rc.1
25
+ def build(name, object, metadata, options = {})
26
+ relation = create_relation(object, metadata)
27
+ set(name, relation).tap do |relation|
28
+ relation.load!(options) if relation && options[:eager]
29
+ end
30
+ end
31
+
32
+ # Return the options passed to the builders.
33
+ #
34
+ # @example Get the options.
35
+ # person.configurables(document, :continue => true)
36
+ #
37
+ # @param [ Array ] args The arguments to check.
38
+ #
39
+ # @return [ Hash ] The options.
40
+ #
41
+ # @since 2.0.0.rc.1
42
+ def options(args)
43
+ Mongoid.binding_defaults.merge(args.extract_options!)
44
+ end
45
+
46
+ # Create a relation from an object and metadata.
47
+ #
48
+ # @example Create the relation.
49
+ # person.create_relation(document, metadata)
50
+ #
51
+ # @param [ Document, Array<Document ] object The relation target.
52
+ # @param [ Metadata ] metadata The relation metadata.
53
+ #
54
+ # @return [ Proxy ] The relation.
55
+ #
56
+ # @since 2.0.0.rc.1
57
+ def create_relation(object, metadata)
58
+ type = @attributes[metadata.inverse_type]
59
+ target = metadata.builder(object).build(type)
60
+ target ? metadata.relation.new(self, target, metadata) : nil
61
+ end
62
+
63
+ # Determines if the relation exists or not.
64
+ #
65
+ # @example Does the relation exist?
66
+ # person.relation_exists?(:people)
67
+ #
68
+ # @param [ String ] name The name of the relation to check.
69
+ #
70
+ # @return [ true, false ] True if set and not nil, false if not.
71
+ #
72
+ # @since 2.0.0.rc.1
73
+ def relation_exists?(name)
74
+ ivar(name)
75
+ end
76
+
77
+ # Set the supplied relation to an instance variable on the class with the
78
+ # provided name. Used as a helper just for code cleanliness.
79
+ #
80
+ # @example Set the proxy on the document.
81
+ # person.set(:addresses, addresses)
82
+ #
83
+ # @param [ String, Symbol ] name The name of the relation.
84
+ # @param [ Proxy ] relation The relation to set.
85
+ #
86
+ # @return [ Proxy ] The relation.
87
+ #
88
+ # @since 2.0.0.rc.1
89
+ def set(name, relation)
90
+ instance_variable_set("@#{name}", relation)
91
+ end
92
+
93
+ # Replace an existing relation with a new one.
94
+ #
95
+ # @example Replace the relation.
96
+ # document.substitute("addresses", Address.new)
97
+ #
98
+ # @param [ String ] name The name of the relation.
99
+ # @param [ Document ] object The document to replace with.
100
+ # @options [ Hash ] options The options.
101
+ #
102
+ # @since 2.0.0
103
+ def substitute(name, object, options)
104
+ set(name, ivar(name).substitute(object, options))
105
+ end
106
+
107
+ module ClassMethods #:nodoc:
108
+
109
+ # Defines the getter for the relation. Nothing too special here: just
110
+ # return the instance variable for the relation if it exists or build
111
+ # the thing.
112
+ #
113
+ # @example Set up the getter for the relation.
114
+ # Person.getter("addresses", metadata)
115
+ #
116
+ # @param [ String, Symbol ] name The name of the relation.
117
+ # @param [ Metadata ] metadata The metadata for the relation.
118
+ #
119
+ # @return [ Class ] The class being set up.
120
+ #
121
+ # @since 2.0.0.rc.1
122
+ def getter(name, metadata)
123
+ tap do
124
+ define_method(name) do |*args|
125
+ reload, variable = args.first, "@#{name}"
126
+ options = options(args)
127
+ if instance_variable_defined?(variable) && !reload
128
+ instance_variable_get(variable)
129
+ else
130
+ build(
131
+ name,
132
+ @attributes[metadata.key],
133
+ metadata,
134
+ options.merge(:binding => true, :eager => metadata.embedded?)
135
+ )
136
+ end
137
+ end
138
+ end
139
+ end
140
+
141
+ # Defines the setter for the relation. This does a few things based on
142
+ # some conditions. If there is an existing association, a target
143
+ # substitution will take place, otherwise a new relation will be
144
+ # created with the supplied target.
145
+ #
146
+ # @example Set up the setter for the relation.
147
+ # Person.setter("addresses", metadata)
148
+ #
149
+ # @param [ String, Symbol ] name The name of the relation.
150
+ # @param [ Metadata ] metadata The metadata for the relation.
151
+ #
152
+ # @return [ Class ] The class being set up.
153
+ #
154
+ # @since 2.0.0.rc.1
155
+ def setter(name, metadata)
156
+ tap do
157
+ define_method("#{name}=") do |*args|
158
+ object, options = args.first, options(args)
159
+ variable = "@#{name}"
160
+ if relation_exists?(name) && !object.is_a?(Hash)
161
+ substitute(name, object, options)
162
+ else
163
+ if metadata.embedded? && object.blank? && send(name)
164
+ substitute(name, object, options)
165
+ else
166
+ build(name, object, metadata, options.merge(:eager => true))
167
+ end
168
+ end
169
+ end
170
+ end
171
+ end
172
+ end
173
+ end
174
+ end
175
+ end