Class: DataMapper::Associations::ManyToOne::Relationship

Inherits:
Relationship show all
Defined in:
lib/dm-core/associations/many_to_one.rb

Overview

Relationship class with implementation specific to n side of 1 to n association

Constant Summary collapse

OPTIONS =
superclass::OPTIONS.dup << :required << :key

Instance Attribute Summary

Attributes inherited from Relationship

#child_repository_name, #instance_variable_name, #max, #min, #name, #options, #parent_repository_name, #query, #reader_visibility, #writer_visibility

Instance Method Summary collapse

Methods inherited from Relationship

#==, #child_model, #child_model?, #child_model_name, #eager_load, #eql?, #field, #get!, #hash, #inverse, #loaded?, #parent_key, #parent_model, #parent_model?, #parent_model_name, #query_for, #relative_target_repository_name, #relative_target_repository_name_for, #set!, #valid?

Methods included from Subject

#default?

Methods included from DataMapper::Assertions

#assert_kind_of

Instance Method Details

#child_keyDataMapper::PropertySet Also known as: source_key

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 a set of keys that identify child model

Returns:



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/dm-core/associations/many_to_one.rb', line 45

def child_key
  return @child_key if defined?(@child_key)

  model           = child_model
  repository_name = child_repository_name || parent_repository_name
  properties      = model.properties(repository_name)

  child_key = parent_key.zip(@child_properties || []).map do |parent_property, property_name|
    property_name ||= "#{name}_#{parent_property.name}".to_sym

    properties[property_name] || begin
      # create the property within the correct repository
      DataMapper.repository(repository_name) do
        model.property(property_name, parent_property.to_child_key, child_key_options(parent_property))
      end
    end
  end

  @child_key = properties.class.new(child_key).freeze
end

#default_for(source) ⇒ Object



141
142
143
# File 'lib/dm-core/associations/many_to_one.rb', line 141

def default_for(source)
  typecast(super)
end

#get(source, query = nil) ⇒ Object

Loads and returns association target (ex.: author) for given source resource (ex.: article)

Parameters:



113
114
115
116
117
# File 'lib/dm-core/associations/many_to_one.rb', line 113

def get(source, query = nil)
  lazy_load(source)
  collection = get_collection(source)
  collection.first(query) if collection
end

#get_collection(source) ⇒ Object



119
120
121
122
# File 'lib/dm-core/associations/many_to_one.rb', line 119

def get_collection(source)
  resource = get!(source)
  resource.collection_for_self if resource
end

#key?Boolean

Returns:

  • (Boolean)


30
31
32
# File 'lib/dm-core/associations/many_to_one.rb', line 30

def key?
  @key
end

#lazy_load(source) ⇒ undefined

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.

Loads association target and sets resulting value on given source resource

Parameters:

  • source (Resource)

    the source resource for the association

Returns:

  • (undefined)


154
155
156
157
158
159
160
161
162
163
164
165
166
# File 'lib/dm-core/associations/many_to_one.rb', line 154

def lazy_load(source)
  return if loaded?(source) || !valid_source?(source)

  # SEL: load all related resources in the source collection
  collection = source.collection
  if source.saved? && collection.size > 1
    eager_load(collection)
  end

  unless loaded?(source)
    set!(source, resource_for(source))
  end
end

#nullable?Boolean

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:

  • (Boolean)


35
36
37
38
39
# File 'lib/dm-core/associations/many_to_one.rb', line 35

def nullable?
  klass = self.class
  warn "#{klass}#nullable? is deprecated, use #{klass}#required? instead (#{caller[0]})"
  !required?
end

#required?Boolean

Returns:

  • (Boolean)


25
26
27
# File 'lib/dm-core/associations/many_to_one.rb', line 25

def required?
  @required
end

#resource_for(source, other_query = nil) ⇒ Resource

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 a Resource for this relationship with a given source

Parameters:

  • source (Resource)

    A Resource to scope the collection with

  • other_query (Query) (defaults to: nil)

    (optional) A Query to further scope the collection with

Returns:

  • (Resource)

    The resource scoped to the relationship, source and query



95
96
97
98
99
100
101
102
# File 'lib/dm-core/associations/many_to_one.rb', line 95

def resource_for(source, other_query = nil)
  query = query_for(source, other_query)

  # TODO: lookup the resource in the Identity Map, and make sure
  # it matches the query criteria, otherwise perform the query

  target_model.first(query)
end

#set(source, target) ⇒ Object

Sets value of association target (ex.: author) for given source resource (ex.: article)

Parameters:



134
135
136
137
138
# File 'lib/dm-core/associations/many_to_one.rb', line 134

def set(source, target)
  target = typecast(target)
  source_key.set(source, target_key.get(target))
  set!(source, target)
end

#source_scope(source) ⇒ Hash

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 a hash of conditions that scopes query that fetches target object

Returns:

  • (Hash)

    Hash of conditions that scopes query



76
77
78
79
80
81
82
# File 'lib/dm-core/associations/many_to_one.rb', line 76

def source_scope(source)
  if source.kind_of?(Resource)
    Query.target_conditions(source, source_key, target_key)
  else
    super
  end
end