mongoid 2.0.0.beta.12 → 2.0.0.beta.13

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.
@@ -11,7 +11,7 @@ Mongoid is an ODM (Object-Document-Mapper) framework for MongoDB in Ruby.
11
11
 
12
12
  == Compatibility
13
13
 
14
- Mongoid is developed against Ruby 1.8.7, 1.9.1, 1.9.2
14
+ Mongoid is developed against Ruby 1.8.7, 1.9.1, 1.9.2, and REE.
15
15
 
16
16
  = Documentation
17
17
 
@@ -149,19 +149,18 @@ module Mongoid #:nodoc:
149
149
  extends(options)
150
150
  end
151
151
 
152
-
153
-
154
152
  # If the target array does not respond to the supplied method then try to
155
153
  # find a named scope or criteria on the class and send the call there.
156
154
  #
157
155
  # If the method exists on the array, use the default proxy behavior.
158
156
  def method_missing(name, *args, &block)
159
- unless @target.respond_to?(name)
160
- object = @klass.send(name, *args)
161
- object.documents = @target
162
- return object
157
+ if @target.respond_to?(name)
158
+ super
159
+ else
160
+ @klass.send(:with_scope, criteria) do
161
+ object = @klass.send(name, *args)
162
+ end
163
163
  end
164
- super
165
164
  end
166
165
 
167
166
  # Used for setting associations via a nested attributes setter from the
@@ -242,6 +241,14 @@ module Mongoid #:nodoc:
242
241
  end; count
243
242
  end
244
243
 
244
+ # Returns the criteria object for the target class with its documents set
245
+ # to @target.
246
+ def criteria
247
+ criteria = @klass.criteria
248
+ criteria.documents = @target
249
+ criteria
250
+ end
251
+
245
252
  class << self
246
253
 
247
254
  # Preferred method of creating a new +EmbedsMany+ association. It will
@@ -32,6 +32,7 @@ module Mongoid #:nodoc:
32
32
  end
33
33
  end
34
34
  @target << object
35
+ object.save unless @parent.new_record?
35
36
  end
36
37
  end
37
38
 
@@ -166,7 +166,7 @@ module Mongoid #:nodoc
166
166
  _master(settings)
167
167
  _slaves(settings)
168
168
  settings.except("database", "slaves").each_pair do |name, value|
169
- send("#{name}=", value) if respond_to?(name)
169
+ send("#{name}=", value) if respond_to?("#{name}=")
170
170
  end
171
171
  end
172
172
 
@@ -63,12 +63,6 @@ module Mongoid #:nodoc:
63
63
  end
64
64
  end
65
65
 
66
- # Returns true if the supplied +Object+ is an instance of +Criteria+ or
67
- # +Scope+.
68
- def self.===(other)
69
- super || Scope === other
70
- end
71
-
72
66
  # Return or create the context in which this criteria should be executed.
73
67
  #
74
68
  # This will return an Enumerable context if the class is embedded,
@@ -153,9 +147,9 @@ module Mongoid #:nodoc:
153
147
  # Returns: <tt>Criteria</tt>
154
148
  def method_missing(name, *args)
155
149
  if @klass.respond_to?(name)
156
- new_scope = @klass.send(name, *args)
157
- new_scope.merge(self) if Criteria === new_scope
158
- return new_scope
150
+ @klass.send(:with_scope, self) do
151
+ @klass.send(name, *args)
152
+ end
159
153
  else
160
154
  return entries.send(name, *args)
161
155
  end
@@ -13,6 +13,17 @@ module Mongoid #:nodoc:
13
13
  end
14
14
  end
15
15
 
16
+ class << self
17
+
18
+ # Returns all classes that have included Mongoid::Document.
19
+ #
20
+ # This will not get subclasses of the top level models, for those we will
21
+ # use Class.descendents in the rake task for indexes.
22
+ def descendants
23
+ (@@descendants ||= {}).keys
24
+ end
25
+ end
26
+
16
27
  module ClassMethods #:nodoc:
17
28
 
18
29
  # Perform default behavior but mark the hierarchy as being hereditary.
@@ -42,17 +53,12 @@ module Mongoid #:nodoc:
42
53
  end
43
54
  end
44
55
 
45
- # Returns the classes that have included Mongoid::Document
46
- def self.descendents
47
- (@@descendants ||= {}).keys
48
- end
49
-
50
56
  # Returns all types to query for when using this class as the base.
51
57
  # *subclasses* is from activesupport. Note that a bug in *subclasses*
52
58
  # causes the first call to only return direct children, hence
53
59
  # the double call and unique.
54
60
  def _types
55
- @_type ||= [subclasses + subclasses + [self.name]].flatten.uniq.map(&:to_s)
61
+ @_type ||= [descendants + [self]].flatten.uniq.map(&:to_s)
56
62
  end
57
63
  end
58
64
 
@@ -39,13 +39,14 @@ module Mongoid #:nodoc:
39
39
  Criteria.translate(self, *args).limit(1).count == 1
40
40
  end
41
41
 
42
- # Helper to initialize a new +Criteria+ object for this class.
42
+ # Helper to initialize a new +Criteria+ object for this class, or return
43
+ # the currently scoped +Criteria+ object.
43
44
  #
44
45
  # Example:
45
46
  #
46
47
  # <tt>Person.criteria</tt>
47
48
  def criteria
48
- Criteria.new(self)
49
+ scope_stack.last || Criteria.new(self)
49
50
  end
50
51
 
51
52
  # Find a +Document+ in several different ways.
@@ -141,5 +142,24 @@ module Mongoid #:nodoc:
141
142
  def find_or(method, attrs = {})
142
143
  first(:conditions => attrs) || send(method, attrs)
143
144
  end
145
+
146
+ # Initializes and returns the current scope stack.
147
+ def scope_stack
148
+ scope_stack_for = Thread.current[:mongoid_scope_stack] ||= {}
149
+ scope_stack_for[object_id] ||= []
150
+ end
151
+
152
+ # Pushes the provided criteria onto the scope stack, and removes it after the
153
+ # provided block is yielded.
154
+ def with_scope(criteria)
155
+ scope_stack = self.scope_stack
156
+ scope_stack << criteria
157
+
158
+ begin
159
+ yield criteria
160
+ ensure
161
+ scope_stack.pop
162
+ end
163
+ end
144
164
  end
145
165
  end
@@ -12,9 +12,9 @@ module Mongoid #:nodoc
12
12
  # Send the actual index creation comments to the MongoDB driver
13
13
  def create_indexes
14
14
  return unless index_options
15
-
15
+ current_collection = self._collection || set_collection
16
16
  index_options.each do |name, options|
17
- self._collection.create_index(name, options)
17
+ current_collection.create_index(name, options)
18
18
  end
19
19
  end
20
20
 
@@ -14,6 +14,5 @@ module Mongoid
14
14
  def inspect
15
15
  "#<Mongoid::Logger:0x#{object_id.to_s(16)} @logger=#{logger.inspect}>"
16
16
  end
17
-
18
17
  end
19
18
  end
@@ -16,14 +16,13 @@ module Mongoid #:nodoc:
16
16
  # named_scope :count_gt_one, :where => { :count.gt => 1 }
17
17
  # named_scope :at_least_count, lambda { |count| { :where => { :count.gt => count } } }
18
18
  # end
19
- def named_scope(name, options = {}, &block)
19
+ def named_scope(name, conditions = {}, &block)
20
20
  name = name.to_sym
21
- scopes[name] = lambda do |parent, *args|
22
- Scope.new(parent, options.scoped(*args), &block)
23
- end
21
+ scopes[name] = Scope.new(conditions, &block)
24
22
  (class << self; self; end).class_eval <<-EOT
25
23
  def #{name}(*args)
26
- scopes[:#{name}].call(self, *args)
24
+ scope = scopes[:#{name}]
25
+ scope.extend(criteria.fuse(scope.conditions.scoped(*args)))
27
26
  end
28
27
  EOT
29
28
  end
@@ -1,6 +1,9 @@
1
+ # encoding: utf-8
1
2
  require "singleton"
2
- require "rails"
3
3
  require "mongoid/config"
4
+ require "rails"
5
+ require "rails/mongoid"
6
+
4
7
  module Rails #:nodoc:
5
8
  module Mongoid #:nodoc:
6
9
  class Railtie < Rails::Railtie #:nodoc:
@@ -50,6 +53,9 @@ module Rails #:nodoc:
50
53
  end
51
54
  end
52
55
 
56
+ # After initialization we will attempt to connect to the database, if
57
+ # we get an exception and can't find a mongoid.yml we will alert the user
58
+ # to generate one.
53
59
  initializer "verify that mongoid is configured" do
54
60
  config.after_initialize do
55
61
  begin
@@ -63,8 +69,20 @@ module Rails #:nodoc:
63
69
  end
64
70
  end
65
71
 
72
+ # Due to all models not getting loaded and messing up inheritance queries
73
+ # and indexing, we need to preload the models in order to address this.
74
+ #
75
+ # This will happen every request in development, once in ther other
76
+ # environments.
77
+ initializer "preload all application models" do |app|
78
+ config.to_prepare do
79
+ ::Rails::Mongoid.load_models(app)
80
+ end
81
+ end
82
+
66
83
  initializer "reconnect to master if application is preloaded" do
67
84
  config.after_initialize do
85
+
68
86
  # Unicorn clears the START_CTX when a worker is forked, so if we have
69
87
  # data in START_CTX then we know we're being preloaded. Unicorn does
70
88
  # not provide application-level hooks for executing code after the
@@ -57,9 +57,7 @@ namespace :db do
57
57
  if not Rake::Task.task_defined?("db:create_indexes")
58
58
  desc 'Create the indexes defined on your mongoid models'
59
59
  task :create_indexes => :environment do
60
- Mongoid::Document.descendents.each do |model|
61
- model.create_indexes
62
- end
60
+ ::Rails::Mongoid.index_children(Mongoid::Document.descendants)
63
61
  end
64
62
  end
65
63
 
@@ -2,74 +2,25 @@
2
2
  module Mongoid #:nodoc:
3
3
  class Scope #:nodoc:
4
4
 
5
- delegate :scopes, :to => :parent
5
+ attr_reader :conditions, :extensions
6
6
 
7
- attr_reader :parent, :conditions
8
-
9
- # If the other is a scope then compare the parent and conditions, otherwise
10
- # if its enumerable collect and compare.
11
- def ==(other)
12
- case other
13
- when Scope
14
- @parent == other.parent && @conditions == other.conditions
15
- when Enumerable
16
- @collection ||= entries
17
- return (@collection == other)
18
- else
19
- return false
20
- end
21
- end
22
-
23
- # Create the new +Scope+. If a block is passed in, this Scope will extend
24
- # the block.
7
+ # Create the new +Scope+. If a block is passed in, this Scope will store
8
+ # the block for future calls to #extend.
25
9
  #
26
10
  # Options:
27
11
  #
28
- # parent: The class the scope belongs to, or a parent +Scope+.
29
12
  # conditions: A +Hash+ of conditions.
13
+ # block: A +block+ of extension methods (optional)
30
14
  #
31
- # Example:
32
- #
33
- # Mongoid::Scope.new(Person, { :title => "Sir" }) do
34
- # def knighted?
35
- # title == "Sir"
36
- # end
37
- # end
38
- def initialize(parent, conditions, &block)
39
- @parent, @conditions = parent, conditions
40
- extend Module.new(&block) if block_given?
15
+ def initialize(conditions = {}, &block)
16
+ @conditions = conditions
17
+ @extensions = Module.new(&block) if block_given?
41
18
  end
42
19
 
43
- # Return the class for the +Scope+. This will be the parent if the parent
44
- # is a class, otherwise will be nil.
45
- def klass
46
- @klass ||= @parent unless @parent.is_a?(Scope)
20
+ def extend(criteria)
21
+ @extensions ? criteria.extend(@extensions) : criteria
47
22
  end
48
23
 
49
- # Chaining is supported through method_missing. If a scope is already
50
- # defined with the method name the call will be passed there, otherwise it
51
- # will be passed to the target or parent.
52
- def method_missing(name, *args, &block)
53
- if scopes.include?(name)
54
- scopes[name].call(self, *args)
55
- elsif klass
56
- target.send(name, *args, &block)
57
- else
58
- @parent.fuse(@conditions); @parent.send(name, *args, &block)
59
- end
60
- end
61
-
62
- # The +Scope+ must respond like a +Criteria+ object. If this is a parent
63
- # criteria delegate to the target, otherwise bubble up to the parent.
64
- def respond_to?(name)
65
- super || (klass ? target.respond_to?(name) : @parent.respond_to?(name))
66
- end
67
-
68
- # Returns the target criteria if it has already been set or creates a new
69
- # criteria from the parent class.
70
- def target
71
- @target ||= klass.criteria.fuse(@conditions)
72
- end
73
24
  end
74
25
  end
75
26
 
@@ -21,16 +21,12 @@ module Mongoid #:nodoc:
21
21
  def validate_each(document, attribute, value)
22
22
  if document.embedded?
23
23
  return if document._parent.nil?
24
-
25
24
  criteria = document._parent.send(document.association_name)
26
-
27
25
  # If the parent document embeds_one, no need to validate uniqueness
28
26
  return if criteria.is_a?(Mongoid::Document)
29
-
30
27
  criteria = criteria.where(attribute => value, :_id => {'$ne' => document._id})
31
28
  else
32
29
  criteria = @klass.where(attribute => value)
33
-
34
30
  unless document.new_record?
35
31
  criteria = criteria.where(:_id => {'$ne' => document._id})
36
32
  end
@@ -39,9 +35,12 @@ module Mongoid #:nodoc:
39
35
  Array.wrap(options[:scope]).each do |item|
40
36
  criteria = criteria.where(item => document.attributes[item])
41
37
  end
42
-
43
38
  if criteria.exists?
44
- document.errors.add(attribute, :taken, :default => options[:message], :value => value)
39
+ document.errors.add(
40
+ attribute,
41
+ :taken,
42
+ options.except(:case_sensistive, :scope).merge(:value => value)
43
+ )
45
44
  end
46
45
  end
47
46
 
@@ -1,4 +1,4 @@
1
1
  # encoding: utf-8
2
2
  module Mongoid #:nodoc
3
- VERSION = "2.0.0.beta.12"
3
+ VERSION = "2.0.0.beta.13"
4
4
  end
@@ -0,0 +1,33 @@
1
+ # encoding: utf-8
2
+ module Rails #:nodoc:
3
+ module Mongoid #:nodoc:
4
+ class << self
5
+
6
+ # Use the application configuration to get every model and require it, so
7
+ # that indexing and inheritance work in both development and production
8
+ # with the same results.
9
+ def load_models(app)
10
+ app.config.paths.app.models.each do |path|
11
+ Dir.glob("#{path}/**/*.rb").sort.each do |file|
12
+ require_dependency(file)
13
+ end
14
+ end
15
+ end
16
+
17
+ # Recursive function to create all the indexes for the model, then
18
+ # potentially and subclass of the model since both are still root
19
+ # documents in the hierarchy.
20
+ #
21
+ # Note there is a tricky naming scheme going on here that needs to be
22
+ # revisisted. Module.descendants vs Class.descendents is way too
23
+ # confusing.
24
+ def index_children(children)
25
+ children.each do |model|
26
+ Logger.new($stdout).info("Generating indexes for #{model}")
27
+ model.create_indexes
28
+ index_children(model.descendants)
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mongoid
3
3
  version: !ruby/object:Gem::Version
4
- hash: 62196475
4
+ hash: 62196473
5
5
  prerelease: true
6
6
  segments:
7
7
  - 2
8
8
  - 0
9
9
  - 0
10
10
  - beta
11
- - 12
12
- version: 2.0.0.beta.12
11
+ - 13
12
+ version: 2.0.0.beta.13
13
13
  platform: ruby
14
14
  authors:
15
15
  - Durran Jordan
@@ -17,7 +17,7 @@ autorequire:
17
17
  bindir: bin
18
18
  cert_chain: []
19
19
 
20
- date: 2010-07-26 00:00:00 -04:00
20
+ date: 2010-07-27 00:00:00 -04:00
21
21
  default_executable:
22
22
  dependencies:
23
23
  - !ruby/object:Gem::Dependency
@@ -26,15 +26,15 @@ dependencies:
26
26
  requirement: &id001 !ruby/object:Gem::Requirement
27
27
  none: false
28
28
  requirements:
29
- - - ~>
29
+ - - "="
30
30
  - !ruby/object:Gem::Version
31
- hash: 31098225
31
+ hash: 7712042
32
32
  segments:
33
33
  - 3
34
34
  - 0
35
35
  - 0
36
- - beta
37
- version: 3.0.0.beta
36
+ - rc
37
+ version: 3.0.0.rc
38
38
  type: :runtime
39
39
  version_requirements: *id001
40
40
  - !ruby/object:Gem::Dependency
@@ -43,7 +43,7 @@ dependencies:
43
43
  requirement: &id002 !ruby/object:Gem::Requirement
44
44
  none: false
45
45
  requirements:
46
- - - ~>
46
+ - - "="
47
47
  - !ruby/object:Gem::Version
48
48
  hash: 63
49
49
  segments:
@@ -75,14 +75,14 @@ dependencies:
75
75
  requirement: &id004 !ruby/object:Gem::Requirement
76
76
  none: false
77
77
  requirements:
78
- - - ~>
78
+ - - "="
79
79
  - !ruby/object:Gem::Version
80
- hash: 29
80
+ hash: 27
81
81
  segments:
82
82
  - 1
83
83
  - 0
84
- - 5
85
- version: 1.0.5
84
+ - 6
85
+ version: 1.0.6
86
86
  type: :runtime
87
87
  version_requirements: *id004
88
88
  - !ruby/object:Gem::Dependency
@@ -91,7 +91,7 @@ dependencies:
91
91
  requirement: &id005 !ruby/object:Gem::Requirement
92
92
  none: false
93
93
  requirements:
94
- - - ~>
94
+ - - "="
95
95
  - !ruby/object:Gem::Version
96
96
  hash: 31
97
97
  segments:
@@ -107,7 +107,7 @@ dependencies:
107
107
  requirement: &id006 !ruby/object:Gem::Requirement
108
108
  none: false
109
109
  requirements:
110
- - - ~>
110
+ - - "="
111
111
  - !ruby/object:Gem::Version
112
112
  hash: 31
113
113
  segments:
@@ -141,14 +141,14 @@ dependencies:
141
141
  requirements:
142
142
  - - "="
143
143
  - !ruby/object:Gem::Version
144
- hash: 62196419
144
+ hash: 62196421
145
145
  segments:
146
146
  - 2
147
147
  - 0
148
148
  - 0
149
149
  - beta
150
- - 16
151
- version: 2.0.0.beta.16
150
+ - 19
151
+ version: 2.0.0.beta.19
152
152
  type: :development
153
153
  version_requirements: *id008
154
154
  - !ruby/object:Gem::Dependency
@@ -297,6 +297,7 @@ files:
297
297
  - lib/rails/generators/mongoid/model/model_generator.rb
298
298
  - lib/rails/generators/mongoid/model/templates/model.rb
299
299
  - lib/rails/generators/mongoid_generator.rb
300
+ - lib/rails/mongoid.rb
300
301
  - MIT_LICENSE
301
302
  - README.rdoc
302
303
  has_rdoc: true