Module: DataMapper::Associations

Includes:
Assertions
Defined in:
lib/dm-core/associations.rb,
lib/dm-core/associations/one_to_one.rb,
lib/dm-core/associations/many_to_one.rb,
lib/dm-core/associations/one_to_many.rb,
lib/dm-core/associations/many_to_many.rb,
lib/dm-core/associations/relationship.rb,
lib/dm-core/associations/relationship_chain.rb

Defined Under Namespace

Modules: ManyToMany, ManyToOne, OneToMany, OneToOne Classes: ImmutableAssociationError, Relationship, RelationshipChain, UnsavedParentError

Instance Method Summary collapse

Methods included from Assertions

#assert_kind_of

Instance Method Details

#belongs_to(name, options = {}) ⇒ DataMapper::Association::ManyToOne

A shorthand, clear syntax for defining many-to-one resource relationships.

Examples:

Usage
* belongs_to :user                          # many_to_one, :friend
* belongs_to :friend, :class_name => 'User'  # many_to_one :friends

Parameters:

  • name (Symbol)

    The name that the association will be referenced by

Returns:

  • (DataMapper::Association::ManyToOne)

    The association created should not be accessed directly

See Also:



147
148
149
150
151
152
153
154
155
156
# File 'lib/dm-core/associations.rb', line 147

def belongs_to(name, options={})
  relationship = ManyToOne.setup(name, self, options)
  # Please leave this in - I will release contextual serialization soon
  # which requires this -- guyvdb
  # TODO convert this to a hook in the plugin once hooks work on class
  # methods
  self.init_belongs_relationship_for_serialization(relationship) if self.respond_to?(:init_belongs_relationship_for_serialization)

  relationship
end

#has(cardinality, name, options = {}) ⇒ DataMapper::Association::Relationship

A shorthand, clear syntax for defining one-to-one, one-to-many and many-to-many resource relationships.

Examples:

Usage
* has 1, :friend                          # one friend
* has n, :friends                         # many friends
* has 1..3, :friends
                      # many friends (at least 1, at most 3)
* has 3, :friends
                      # many friends (exactly 3)
* has 1, :friend, :class_name => 'User'
                      # one friend with the class name User
* has 3, :friends, :through => :friendships
                      # many friends through the friendships relationship
* has n, :friendships => :friends
                      # identical to above example

Parameters:

  • cardinality (Integer, Range, Infinity)

    cardinality that defines the association type and constraints

  • name (Symbol)

    the name that the association will be referenced by

  • opts (Hash)

    an options hash

  • :through[Symbol] (Hash)

    a customizable set of options

  • :class_name[String] (Hash)

    a customizable set of options

  • :remote_name[Symbol] (Hash)

    a customizable set of options

Returns:

  • (DataMapper::Association::Relationship)

    the relationship that was created to reflect either a one-to-one, one-to-many or many-to-many relationship

Raises:

  • (ArgumentError)

    if the cardinality was not understood. Should be a Integer, Range or Infinity(n)



94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
# File 'lib/dm-core/associations.rb', line 94

def has(cardinality, name, options = {})

  # NOTE: the reason for this fix is that with the ability to pass in two
  # hashes into has() there might be instances where people attempt to
  # pass in the options into the name part and not know why things aren't
  # working for them.
  if name.kind_of?(Hash)
    name_through, through = name.keys.first, name.values.first
    cardinality_string = cardinality.to_s == 'Infinity' ? 'n' : cardinality.inspect
    warn("In #{self.name} 'has #{cardinality_string}, #{name_through.inspect} => #{through.inspect}' is deprecated. Use 'has #{cardinality_string}, #{name_through.inspect}, :through => #{through.inspect}' instead")
  end

  options = options.merge(extract_min_max(cardinality))
  options = options.merge(extract_throughness(name))

  # do not remove this. There is alot of confusion on people's
  # part about what the first argument to has() is.  For the record it
  # is the min cardinality and max cardinality of the association.
  # simply put, it constraints the number of resources that will be
  # returned by the association.  It is not, as has been assumed,
  # the number of results on the left and right hand side of the
  # reltionship.
  if options[:min] == n && options[:max] == n
    raise ArgumentError, 'Cardinality may not be n..n.  The cardinality specifies the min/max number of results from the association', caller
  end

  klass = options[:max] == 1 ? OneToOne : OneToMany
  klass = ManyToMany if options[:through] == DataMapper::Resource
  relationship = klass.setup(options.delete(:name), self, options)

  # Please leave this in - I will release contextual serialization soon
  # which requires this -- guyvdb
  # TODO convert this to a hook in the plugin once hooks work on class
  # methods
  self.init_has_relationship_for_serialization(relationship) if self.respond_to?(:init_has_relationship_for_serialization)

  relationship
end

#many_to_one_relationshipsObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns all relationships that are many-to-one for this model.

Used to find the relationships that require properties in any Repository.

Example: class Plur

include DataMapper::Resource
def self.default_repository_name
  :plur_db
end
repository(:plupp_db) do
  has 1, :plupp
end

end

This resource has a many-to-one to the Plupp resource residing in the :plupp_db repository, but the Plur resource needs the plupp_id property no matter what repository itself lives in, ie we need to create that property when we migrate etc.

Used in DataMapper::Model.properties_with_subclasses



42
43
44
45
# File 'lib/dm-core/associations.rb', line 42

def many_to_one_relationships
  relationships unless @relationships # needs to be initialized!
  @relationships.values.collect do |rels| rels.values end.flatten.select do |relationship| relationship.child_model == self end
end

#nObject



52
53
54
# File 'lib/dm-core/associations.rb', line 52

def n
  1.0/0
end

#relationships(repository_name = default_repository_name) ⇒ Object



47
48
49
50
# File 'lib/dm-core/associations.rb', line 47

def relationships(repository_name = default_repository_name)
  @relationships ||= Hash.new { |h,k| h[k] = k == Repository.default_name ? {} : h[Repository.default_name].dup }
  @relationships[repository_name]
end