Class: DataMapper::Associations::ManyToMany::Relationship
- Inherits:
-
OneToMany::Relationship
- Object
- Relationship
- OneToMany::Relationship
- DataMapper::Associations::ManyToMany::Relationship
- Extended by:
- Chainable
- Defined in:
- lib/dm-core/associations/many_to_many.rb
Constant Summary collapse
- OPTIONS =
superclass::OPTIONS.dup << :through << :via
Instance Attribute Summary
Attributes inherited from Relationship
#child_repository_name, #instance_variable_name, #max, #min, #name, #options, #parent_repository_name
Instance Method Summary collapse
-
#child_key ⇒ DataMapper::PropertySet
(also: #target_key)
Returns a set of keys that identify the target model.
-
#eager_load(source, other_query = nil) ⇒ ManyToMany::Collection
private
Eager load the collection using the source as a base.
-
#links ⇒ Object
TODO: document.
-
#query ⇒ Object
private
TODO: document.
-
#source_scope(source) ⇒ Object
private
TODO: document.
-
#through ⇒ Object
Intermediate association for through model relationships.
-
#via ⇒ Object
TODO: document.
Methods included from Chainable
Methods inherited from OneToMany::Relationship
#collection_for, #get, #inherited_by, #set
Methods inherited from Relationship
#==, #child_model, #child_model?, #child_model_name, #eql?, #get, #get!, #inverse, #loaded?, #parent_key, #parent_model, #parent_model?, #parent_model_name, #query_for, #relative_target_repository_name, #relative_target_repository_name_for, #set, #set!, #valid?
Instance Method Details
#child_key ⇒ DataMapper::PropertySet Also known as: target_key
Returns a set of keys that identify the target model
15 16 17 18 19 20 21 22 23 24 25 26 27 |
# File 'lib/dm-core/associations/many_to_many.rb', line 15 def child_key return @child_key if defined?(@child_key) repository_name = child_repository_name || parent_repository_name properties = child_model.properties(repository_name) @child_key = if @child_properties child_key = properties.values_at(*@child_properties) properties.class.new(child_key).freeze else properties.key end end |
#eager_load(source, other_query = nil) ⇒ ManyToMany::Collection
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.
Eager load the collection using the source as a base
148 149 150 151 |
# File 'lib/dm-core/associations/many_to_many.rb', line 148 def eager_load(source, other_query = nil) # FIXME: enable SEL for m:m relationships source.model.all(query_for(source, other_query)) end |
#links ⇒ Object
TODO: document
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 |
# File 'lib/dm-core/associations/many_to_many.rb', line 106 def links return @links if defined?(@links) @links = [] links = [ through, via ] while relationship = links.shift if relationship.respond_to?(:links) links.unshift(*relationship.links) else @links << relationship end end @links.freeze end |
#query ⇒ Object
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.
TODO: document
131 132 133 134 135 |
# File 'lib/dm-core/associations/many_to_many.rb', line 131 def query # TODO: consider making this a query_for method, so that ManyToMany::Relationship#query only # returns the query supplied in the definition @many_to_many_query ||= super.merge(:links => links).freeze end |
#source_scope(source) ⇒ Object
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.
TODO: document
125 126 127 |
# File 'lib/dm-core/associations/many_to_many.rb', line 125 def source_scope(source) { through.inverse => source } end |
#through ⇒ Object
Intermediate association for through model relationships
Example: for :bugs association in
class Software::Engineer
include DataMapper::Resource
has n, :missing_tests
has n, :bugs, :through => :missing_tests
end
through is :missing_tests
TODO: document a case when through option is a model and not an association name
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
# File 'lib/dm-core/associations/many_to_many.rb', line 52 def through return @through if defined?(@through) if [:through].kind_of?(Associations::Relationship) return @through = [:through] end repository_name = source_repository_name relationships = source_model.relationships(repository_name) name = through_relationship_name @through = relationships[name] || DataMapper.repository(repository_name) do source_model.has(min..max, name, through_model, ) end @through.child_key @through end |
#via ⇒ Object
TODO: document
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
# File 'lib/dm-core/associations/many_to_many.rb', line 75 def via return @via if defined?(@via) if [:via].kind_of?(Associations::Relationship) return @via = [:via] end repository_name = through.relative_target_repository_name through_model = through.target_model relationships = through_model.relationships(repository_name) singular_name = name.to_s.singularize.to_sym @via = relationships[[:via]] || relationships[name] || relationships[singular_name] @via ||= if anonymous_through_model? DataMapper.repository(repository_name) do through_model.belongs_to(singular_name, target_model, ) end else raise UnknownRelationshipError, "No relationships named #{name} or #{singular_name} in #{through_model}" end @via.child_key @via end |