Class: PassiveRecord::Associations::HasManyThroughRelation

Inherits:
HasManyRelation show all
Defined in:
lib/passive_record/associations/has_many_through.rb

Instance Attribute Summary

Attributes inherited from Relation

#association, #parent_model

Instance Method Summary collapse

Methods inherited from HasManyRelation

#method_missing, #singular?

Methods included from PassiveRecord::ArithmeticHelpers

#average, #mode, #pluck, #sum

Methods inherited from HasOneRelation

#child_class, #child_class_name, #id, #lookup, #lookup_or_create, #parent_model_id_field

Methods inherited from Relation

#singular?

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class PassiveRecord::Associations::HasManyRelation

Instance Method Details

#<<(child) ⇒ Object



10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/passive_record/associations/has_many_through.rb', line 10

def <<(child)
  if nested_association.is_a?(HasManyAssociation)
    intermediary_id =
      child.send(association.base_association.target_name_symbol.to_s.singularize + "_id")

    if intermediary_id
      intermediary_relation.child_class.find(intermediary_id).
        send(:"#{parent_model_id_field}=", parent_model.id)
    else
      nested_ids_field = nested_association.children_name_sym.to_s.singularize + "_ids"
      intermediary_model = intermediary_relation.singular? ?
          intermediary_relation.lookup_or_create :
          intermediary_relation.where(parent_model_id_field => parent_model.id).first_or_create

      intermediary_model.update(
          nested_ids_field => intermediary_model.send(nested_ids_field) + [ child.id ]
        )
    end
  else
    intermediary_model = intermediary_relation.
      where(
        association.target_name_symbol.to_s.singularize + "_id" => child.id).
        first_or_create
  end
  self
end

#allObject



62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/passive_record/associations/has_many_through.rb', line 62

def all
  join_results = intermediate_results
  if intermediate_results && !join_results.empty?
    final_results = join_results.flat_map(&nested_association.target_name_symbol)
    if final_results.first.is_a?(Associations::Relation)
      final_results.flat_map(&:all).compact
    else
      Array(final_results.compact)
    end
  else
    []
  end
end

#create(attrs = {}) ⇒ Object



37
38
39
40
41
# File 'lib/passive_record/associations/has_many_through.rb', line 37

def create(attrs={})
  child = child_class.create(attrs)
  send(:<<, child)
  child
end

#intermediary_relationObject



76
77
78
# File 'lib/passive_record/associations/has_many_through.rb', line 76

def intermediary_relation
  @intermediary_relation ||= association.base_association.to_relation(parent_model)
end

#intermediate_resultsObject



80
81
82
83
84
85
86
# File 'lib/passive_record/associations/has_many_through.rb', line 80

def intermediate_results
  if intermediary_relation.singular?
    Array(intermediary_relation.lookup)
  else
    intermediary_relation.all
  end
end

#nested_associationObject



50
51
52
53
54
55
56
57
58
59
60
# File 'lib/passive_record/associations/has_many_through.rb', line 50

def nested_association
  nested_class.associations.detect { |assn|
    assn.child_class_name == association.child_class_name ||
    assn.child_class_name == association.child_class_name.singularize ||

    (assn.parent_class_name == association.child_class_name rescue false) ||
    (assn.parent_class_name == association.child_class_name.singularize rescue false) ||

    assn.target_name_symbol == association.target_name_symbol.to_s.singularize.to_sym
  }
end

#nested_classObject



43
44
45
46
47
48
# File 'lib/passive_record/associations/has_many_through.rb', line 43

def nested_class
  module_name = association.parent_class.name.deconstantize
  module_name = "Object" if module_name.empty?
  (module_name.constantize).
    const_get("#{association.base_association.child_class_name.singularize}")
end

#where(conditions = {}) ⇒ Object



88
89
90
91
92
93
94
95
# File 'lib/passive_record/associations/has_many_through.rb', line 88

def where(conditions={})
  Core::HasManyThroughQuery.new(
    child_class,
    parent_model,
    association.target_name_symbol,
    conditions
  )
end