Class: Mongoid::Relations::Referenced::Many

Inherits:
Many show all
Includes:
Batch
Defined in:
lib/mongoid/relations/referenced/many.rb

Overview

This class defines the behaviour for all relations that are a one-to-many between documents in different collections.

Direct Known Subclasses

ManyToMany

Instance Attribute Summary

Attributes inherited from Proxy

#base, #loaded, #metadata, #target

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Many

#build, #exists?, #find_or_create_by, #find_or_initialize_by, #nil?, #respond_to?, #serializable_hash, #size

Methods inherited from Proxy

#init

Constructor Details

#initialize(base, target, metadata) ⇒ Many

Instantiate a new references_many relation. Will set the foreign key and the base on the inverse object.

Examples:

Create the new relation.

Referenced::Many.new(base, target, )

Parameters:

  • base (Document)

    The document this relation hangs off of.

  • target (Array<Document>)

    The target of the relation.

  • metadata (Metadata)

    The relation’s metadata.



202
203
204
# File 'lib/mongoid/relations/referenced/many.rb', line 202

def initialize(base, target, )
  init(base, target, )
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(name, *args, &block) ⇒ Criteria, Object (private)

If the target array does not respond to the supplied method then try to find a named scope or criteria on the class and send the call there.

If the method exists on the array, use the default proxy behavior.

Parameters:

  • name (Symbol, String)

    The name of the method.

  • args (Array)

    The method args

  • block (Proc)

    Optional block to pass.

Returns:



399
400
401
402
403
404
405
# File 'lib/mongoid/relations/referenced/many.rb', line 399

def method_missing(name, *args, &block)
  load!(:binding => true) and return super if [].respond_to?(name)
  klass = .klass
  klass.send(:with_scope, criteria) do
    criteria.send(name, *args, &block)
  end
end

Class Method Details

.builder(meta, object) ⇒ Builder

Return the builder that is responsible for generating the documents that will be used by this relation.

Examples:

Get the builder.

Referenced::Many.builder(meta, object)

Parameters:

  • meta (Metadata)

    The metadata of the relation.

  • object (Document, Hash)

    A document or attributes to build with.

Returns:

  • (Builder)

    A new builder object.

Since:

  • 2.0.0.rc.1



422
423
424
# File 'lib/mongoid/relations/referenced/many.rb', line 422

def builder(meta, object)
  Builders::Referenced::Many.new(meta, object || [])
end

.embedded?false

Returns true if the relation is an embedded one. In this case always false.

Examples:

Is this relation embedded?

Referenced::Many.embedded?

Returns:

  • (false)

    Always false.

Since:

  • 2.0.0.rc.1



435
436
437
# File 'lib/mongoid/relations/referenced/many.rb', line 435

def embedded?
  false
end

.foreign_key_defaultnil

Get the default value for the foreign key.

Examples:

Get the default.

Referenced::Many.foreign_key_default

Returns:

  • (nil)

    Always nil.

Since:

  • 2.0.0.rc.1



447
448
449
# File 'lib/mongoid/relations/referenced/many.rb', line 447

def foreign_key_default
  nil
end

.foreign_key_suffixString

Returns the suffix of the foreign key field, either “_id” or “_ids”.

Examples:

Get the suffix for the foreign key.

Referenced::Many.foreign_key_suffix

Returns:

Since:

  • 2.0.0.rc.1



459
460
461
# File 'lib/mongoid/relations/referenced/many.rb', line 459

def foreign_key_suffix
  "_id"
end

.macroSymbol

Returns the macro for this relation. Used mostly as a helper in reflection.

Examples:

Get the macro.

Referenced::Many.macro

Returns:

  • (Symbol)

    :references_many



470
471
472
# File 'lib/mongoid/relations/referenced/many.rb', line 470

def macro
  :references_many
end

.nested_builder(metadata, attributes, options) ⇒ NestedBuilder

Return the nested builder that is responsible for generating the documents that will be used by this relation.

Examples:

Get the nested builder.

Referenced::Many.builder(attributes, options)

Parameters:

  • metadata (Metadata)

    The relation metadata.

  • attributes (Hash)

    The attributes to build with.

  • options (Hash)

    The options for the builder.

Options Hash (options):

  • :allow_destroy (true, false)

    Can documents be deleted?

  • :limit (Integer)

    Max number of documents to create at once.

  • :reject_if (Proc, Symbol)

    If documents match this option then they are ignored.

  • :update_only (true, false)

    Only existing documents can be modified.

Returns:

  • (NestedBuilder)

    A newly instantiated nested builder object.

Since:

  • 2.0.0.rc.1



496
497
498
# File 'lib/mongoid/relations/referenced/many.rb', line 496

def nested_builder(, attributes, options)
  Builders::NestedAttributes::Many.new(, attributes, options)
end

.stores_foreign_key?false

Tells the caller if this relation is one that stores the foreign key on its own objects.

Examples:

Does this relation store a foreign key?

Referenced::Many.stores_foreign_key?

Returns:

  • (false)

    Always false.

Since:

  • 2.0.0.rc.1



509
510
511
# File 'lib/mongoid/relations/referenced/many.rb', line 509

def stores_foreign_key?
  false
end

Instance Method Details

#<<(*args) ⇒ Object Also known as: concat, push

Appends a document or array of documents to the relation. Will set the parent and update the index in the process.

Examples:

Append a document.

person.posts << post

Push a document.

person.posts.push(post)

Concat with other documents.

person.posts.concat([ post_one, post_two ])

Parameters:



24
25
26
27
28
29
30
31
32
33
# File 'lib/mongoid/relations/referenced/many.rb', line 24

def <<(*args)
  options = default_options(args)
  batched do
    args.flatten.each do |doc|
      return doc unless doc
      append(doc, options)
      doc.save if base.persisted? && !options[:binding]
    end
  end
end

#bind(options = {}) ⇒ Object

Binds the base object to the inverse of the relation. This is so we are referenced to the actual objects themselves and dont hit the database twice when setting the relations up.

This is called after first creating the relation, or if a new object is set on the relation.

Examples:

Bind the relation.

person.posts.bind

Parameters:

  • options (Hash) (defaults to: {})

    The options to bind with.

Options Hash (options):

  • :binding (true, false)

    Are we in build mode?

  • :continue (true, false)

    Continue binding the inverse?

Since:

  • 2.0.0.rc.1



54
55
56
57
# File 'lib/mongoid/relations/referenced/many.rb', line 54

def bind(options = {})
  binding.bind(options)
  target.map(&:save) if base.persisted? && !options[:binding]
end

#clear(options = {}) ⇒ Many

Clear the relation. Will delete the documents from the db if they are already persisted.

Examples:

Clear the relation.

person.posts.clear

Returns:

  • (Many)

    The relation emptied.



69
70
71
72
73
74
# File 'lib/mongoid/relations/referenced/many.rb', line 69

def clear(options = {})
  load! and tap do |relation|
    relation.unbind(default_options(options))
    target.clear
  end
end

#countInteger

Returns a count of the number of documents in the association that have actually been persisted to the database.

Use #size if you want the total number of documents in memory.

Examples:

Get the count of persisted documents.

person.posts.count

Returns:

  • (Integer)

    The total number of persisted documents.



85
86
87
# File 'lib/mongoid/relations/referenced/many.rb', line 85

def count
  criteria.count
end

#create(attributes = nil, type = nil, &block) ⇒ Document

Creates a new document on the references many relation. This will save the document if the parent has been persisted.

Examples:

Create and save the new document.

person.posts.create(:text => "Testing")

Parameters:

  • attributes (Hash) (defaults to: nil)

    The attributes to create with.

  • type (Class) (defaults to: nil)

    The optional type of document to create.

Returns:

  • (Document)

    The newly created document.



99
100
101
102
103
# File 'lib/mongoid/relations/referenced/many.rb', line 99

def create(attributes = nil, type = nil, &block)
  build(attributes, type, &block).tap do |doc|
    base.persisted? ? doc.save : raise_unsaved(doc)
  end
end

#create!(attributes = nil, type = nil, &block) ⇒ Document

Creates a new document on the references many relation. This will save the document if the parent has been persisted and will raise an error if validation fails.

Examples:

Create and save the new document.

person.posts.create!(:text => "Testing")

Parameters:

  • attributes (Hash) (defaults to: nil)

    The attributes to create with.

  • type (Class) (defaults to: nil)

    The optional type of document to create.

Returns:

  • (Document)

    The newly created document.

Raises:



118
119
120
121
122
# File 'lib/mongoid/relations/referenced/many.rb', line 118

def create!(attributes = nil, type = nil, &block)
  build(attributes, type, &block).tap do |doc|
    base.persisted? ? doc.save! : raise_unsaved(doc)
  end
end

#delete_all(conditions = nil) ⇒ Integer

Deletes all related documents from the database given the supplied conditions.

Examples:

Delete all documents in the relation.

person.posts.delete_all

Conditonally delete all documents in the relation.

person.posts.delete_all(:conditions => { :title => "Testing" })

Parameters:

  • conditions (Hash) (defaults to: nil)

    Optional conditions to delete with.

Returns:

  • (Integer)

    The number of documents deleted.



136
137
138
139
140
141
142
143
# File 'lib/mongoid/relations/referenced/many.rb', line 136

def delete_all(conditions = nil)
  raise_mixed if klass.embedded?
  selector = (conditions || {})[:conditions] || {}
  target.delete_if { |doc| doc.matches?(selector) }
  .klass.delete_all(
    :conditions => criteria.selector.merge(selector)
  )
end

#destroy_all(conditions = nil) ⇒ Integer

Destroys all related documents from the database given the supplied conditions.

Examples:

Destroy all documents in the relation.

person.posts.destroy_all

Conditonally destroy all documents in the relation.

person.posts.destroy_all(:conditions => { :title => "Testing" })

Parameters:

  • conditions (Hash) (defaults to: nil)

    Optional conditions to destroy with.

Returns:

  • (Integer)

    The number of documents destroyd.



157
158
159
160
161
162
163
164
# File 'lib/mongoid/relations/referenced/many.rb', line 157

def destroy_all(conditions = nil)
  raise_mixed if klass.embedded?
  selector = (conditions || {})[:conditions] || {}
  target.delete_if { |doc| doc.matches?(selector) }
  .klass.destroy_all(
    :conditions => criteria.selector.merge(selector)
  )
end

#find(*args) ⇒ Document, Criteria

Find the matchind document on the association, either based on id or conditions.

Examples:

Find by an id.

person.posts.find(BSON::ObjectId.new)

Find by multiple ids.

person.posts.find([ BSON::ObjectId.new, BSON::ObjectId.new ])

Conditionally find all matching documents.

person.posts.find(:all, :conditions => { :title => "Sir" })

Conditionally find the first document.

person.posts.find(:first, :conditions => { :title => "Sir" })

Conditionally find the last document.

person.posts.find(:last, :conditions => { :title => "Sir" })

Parameters:

Returns:



189
190
191
# File 'lib/mongoid/relations/referenced/many.rb', line 189

def find(*args)
  criteria.find(*args)
end

#load!(options = {}) ⇒ Many

Will load the target into an array if the target had not already been loaded.

Examples:

Load the relation into memory.

relation.load!

Returns:

  • (Many)

    The relation.

Since:

  • 2.0.0.rc.5



215
216
217
218
219
220
221
222
223
224
# File 'lib/mongoid/relations/referenced/many.rb', line 215

def load!(options = {})
  raise_mixed if klass.embedded?
  tap do |relation|
    unless relation.loaded?
      relation.target = target.entries
      relation.bind(options)
      relation.loaded = true
    end
  end
end

#nullifyObject Also known as: nullify_all

Removes all associations between the base document and the target documents by deleting the foreign keys and the references, orphaning the target documents in the process.

Examples:

Nullify the relation.

person.posts.nullify

Since:

  • 2.0.0.rc.1



234
235
236
# File 'lib/mongoid/relations/referenced/many.rb', line 234

def nullify
  clear(:binding => true, :continue => true, :nullify => true)
end

#substitute(target, options = {}) ⇒ Many

Substitutes the supplied target documents for the existing documents in the relation. If the new target is nil, perform the necessary deletion.

Examples:

Replace the relation.

person.posts.substitute(new_name)

Parameters:

  • target (Array<Document>)

    The replacement target.

  • options (Hash) (defaults to: {})

    The options to bind with.

Options Hash (options):

  • :binding (true, false)

    Are we in build mode?

  • :continue (true, false)

    Continue binding the inverse?

Returns:

  • (Many)

    The relation.

Since:

  • 2.0.0.rc.1



256
257
258
# File 'lib/mongoid/relations/referenced/many.rb', line 256

def substitute(target, options = {})
  tap { target ? (@target = target.to_a; bind(options)) : (@target = unbind(options)) }
end

#unbind(options = {}) ⇒ Object

Unbinds the base object to the inverse of the relation. This occurs when setting a side of the relation to nil.

Will delete the object if necessary.

Examples:

Unbind the target.

person.posts.unbind

Parameters:

  • options (Hash) (defaults to: {})

    The options to bind with.

Options Hash (options):

  • :binding (true, false)

    Are we in build mode?

  • :continue (true, false)

    Continue binding the inverse?

Since:

  • 2.0.0.rc.1



275
276
277
278
279
280
281
282
# File 'lib/mongoid/relations/referenced/many.rb', line 275

def unbind(options = {})
  binding.unbind(options)
  unless base.new_record?
    target.each(&:delete) unless options[:binding]
    target.each(&:save) if options[:nullify]
  end
  []
end