module Mongoid::Relations::Macros::ClassMethods
Public Instance Methods
Adds a relational association from the child Document to a Document in another database or collection.
@example Define the relation.
class Game include Mongoid::Document belongs_to :person end class Person include Mongoid::Document has_one :game end
@param [ Symbol ] name The name of the relation. @param [ Hash ] options The relation options. @param [ Proc ] block Optional block for defining extensions.
# File lib/mongoid/relations/macros.rb, line 137 def belongs_to(name, options = {}, &block) meta = reference_one_to_one(name, options, Referenced::In, &block) aliased_fields[name.to_s] = meta.foreign_key touchable(meta) add_counter_cache_callbacks(meta) if meta.counter_cached? meta end
Adds the relation back to the parent document. This macro is necessary to set the references from the child back to the parent document. If a child does not define this relation calling persistence methods on the child object will cause a save to fail.
@example Define the relation.
class Person include Mongoid::Document embeds_many :addresses end class Address include Mongoid::Document embedded_in :person end
@param [ Symbol ] name The name of the relation. @param [ Hash ] options The relation options. @param [ Proc ] block Optional block for defining extensions.
# File lib/mongoid/relations/macros.rb, line 52 def embedded_in(name, options = {}, &block) meta = characterize(name, Embedded::In, options, &block) self.embedded = true relate(name, meta) builder(name, meta).creator(name, meta) touchable(meta) add_counter_cache_callbacks(meta) if meta.counter_cached? meta end
Adds the relation from a parent document to its children. The name of the relation needs to be a pluralized form of the child class name.
@example Define the relation.
class Person include Mongoid::Document embeds_many :addresses end class Address include Mongoid::Document embedded_in :person end
@param [ Symbol ] name The name of the relation. @param [ Hash ] options The relation options. @param [ Proc ] block Optional block for defining extensions.
# File lib/mongoid/relations/macros.rb, line 81 def embeds_many(name, options = {}, &block) meta = characterize(name, Embedded::Many, options, &block) self.cyclic = true if options[:cyclic] relate(name, meta) embed(name, meta) validates_relation(meta) meta end
Adds the relation from a parent document to its child. The name of the relation needs to be a singular form of the child class name.
@example Define the relation.
class Person include Mongoid::Document embeds_one :name end class Name include Mongoid::Document embedded_in :person end
@param [ Symbol ] name The name of the relation. @param [ Hash ] options The relation options. @param [ Proc ] block Optional block for defining extensions.
# File lib/mongoid/relations/macros.rb, line 109 def embeds_one(name, options = {}, &block) meta = characterize(name, Embedded::One, options, &block) self.cyclic = true if options[:cyclic] relate(name, meta) embed(name, meta) builder(name, meta).creator(name, meta) validates_relation(meta) meta end
Adds a relational many-to-many association between many of this Document and many of another Document.
@example Define the relation.
class Person include Mongoid::Document has_and_belongs_to_many :preferences end class Preference include Mongoid::Document has_and_belongs_to_many :people end
@param [ Symbol ] name The name of the relation. @param [ Hash ] options The relation options. @param [ Proc ] block Optional block for defining extensions.
@since 2.0.0.rc.1
# File lib/mongoid/relations/macros.rb, line 193 def has_and_belongs_to_many(name, options = {}, &block) meta = characterize(name, Referenced::ManyToMany, options, &block) relate(name, meta) reference(meta, Array) autosave(meta) validates_relation(meta) synced(meta) meta end
Adds a relational association from a parent Document to many Documents in another database or collection.
@example Define the relation.
class Person include Mongoid::Document has_many :posts end class Game include Mongoid::Document belongs_to :person end
@param [ Symbol ] name The name of the relation. @param [ Hash ] options The relation options. @param [ Proc ] block Optional block for defining extensions.
# File lib/mongoid/relations/macros.rb, line 163 def has_many(name, options = {}, &block) meta = characterize(name, Referenced::Many, options, &block) relate(name, meta) ids_getter(name, meta).ids_setter(name, meta) reference(meta) autosave(meta) validates_relation(meta) meta end
Adds a relational association from the child Document to a Document in another database or collection.
@example Define the relation.
class Game include Mongoid::Document belongs_to :person end class Person include Mongoid::Document has_one :game end
@param [ Symbol ] name The name of the relation. @param [ Hash ] options The relation options. @param [ Proc ] block Optional block for defining extensions.
# File lib/mongoid/relations/macros.rb, line 221 def has_one(name, options = {}, &block) reference_one_to_one(name, options, Referenced::One, &block) end
Private Instance Methods
Create the metadata for the relation.
@api private
@example Create the metadata.
Person.characterize(:posts, Referenced::Many, {})
@param [ Symbol ] name The name of the relation. @param [ Object ] relation The type of relation. @param [ Hash ] options The relation options. @param [ Proc ] block Optional block for defining extensions.
@return [ Metadata ] The metadata for the relation.
# File lib/mongoid/relations/macros.rb, line 240 def characterize(name, relation, options, &block) Metadata.new({ relation: relation, extend: create_extension_module(name, &block), inverse_class_name: self.name, name: name }.merge(options)) end
Generate a named extension module suitable for marshaling
@api private
@example Get the module.
Person.create_extension_module(:posts, &block)
@param [ Symbol ] name The name of the relation. @param [ Proc ] block Optional block for defining extensions.
@return [ Module, nil ] The extension or nil.
@since 2.1.0
# File lib/mongoid/relations/macros.rb, line 262 def create_extension_module(name, &block) if block extension_module_name = "#{self.to_s.demodulize}#{name.to_s.camelize}RelationExtension" silence_warnings do self.const_set(extension_module_name, Module.new(&block)) end "#{self}::#{extension_module_name}".constantize end end
Add an embedded relation metadata to the embedded relations.
@api private
@example Add the metadata to embedded relations.
Person.embed("addresses", metadata)
@param [ String ] name The name of the relation. @param [ Metadata ] metadata The relation metadata.
@since 3.0.0
# File lib/mongoid/relations/macros.rb, line 284 def embed(name, metadata) self.embedded_relations = embedded_relations.merge(name.to_s => metadata) aliased_fields[name.to_s] = metadata.store_as if metadata.store_as end
Defines a field to be used as a foreign key in the relation and indexes it if defined.
@api private
@example Set up the relational fields and indexes.
Person.reference(metadata)
@param [ Metadata ] metadata The metadata for the relation.
# File lib/mongoid/relations/macros.rb, line 298 def reference(metadata, type = Object) polymorph(metadata).cascade(metadata) if metadata.relation.stores_foreign_key? key = metadata.foreign_key field( key, type: type, identity: true, overwrite: true, metadata: metadata, default: metadata.foreign_key_default ) if metadata.indexed? if metadata.polymorphic? index({ key => 1, metadata.inverse_type => 1 }, { background: true }) else index({ key => 1 }, { background: true }) end end end end
Handle common behaviour for referenced 1-1 relation setup.
@api private
@example Add the one to one behaviour.
Model.reference_one_to_one(:name, meta)
@param [ Symbol ] name The name of the relation. @param [ Metadata ] meta The relation metadata.
@return [ Class ] The model class.
@since 3.0.0
# File lib/mongoid/relations/macros.rb, line 333 def reference_one_to_one(name, options, relation, &block) meta = characterize(name, relation, options, &block) relate(name, meta) reference(meta) builder(name, meta).creator(name, meta).autosave(meta) validates_relation(meta) meta end
Creates a relation for the given name, metadata and relation. It adds the metadata to the relations hash and has the accessors set up.
@example Set up the relation and accessors.
Person.relate(:addresses, Metadata)
@param [ Symbol ] name The name of the relation. @param [ Metadata ] metadata The metadata for the relation.
# File lib/mongoid/relations/macros.rb, line 350 def relate(name, metadata) self.relations = relations.merge(name.to_s => metadata) getter(name, metadata).setter(name, metadata).existence_check(name) end