Class: Arerd::Association

Inherits:
Object
  • Object
show all
Includes:
Comparable
Defined in:
lib/arerd/association.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(left_model:, left_key:, left_association_name:, right_model:, right_key:, right_association_name:, left_side_multiplicity:, right_side_multiplicity:) ⇒ Association

Returns a new instance of Association.



11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# File 'lib/arerd/association.rb', line 11

def initialize(
  left_model:,
  left_key:,
  left_association_name:,
  right_model:,
  right_key:,
  right_association_name:,
  left_side_multiplicity:,
  right_side_multiplicity:
)
  @left_model = left_model
  @left_key = left_key
  @left_association_name = left_association_name
  @right_model = right_model
  @right_key = right_key
  @right_association_name = right_association_name
  @left_side_multiplicity = left_side_multiplicity
  @right_side_multiplicity = right_side_multiplicity
end

Instance Attribute Details

#left_association_nameObject (readonly)

Returns the value of attribute left_association_name.



7
8
9
# File 'lib/arerd/association.rb', line 7

def left_association_name
  @left_association_name
end

#left_keyObject (readonly)

Returns the value of attribute left_key.



7
8
9
# File 'lib/arerd/association.rb', line 7

def left_key
  @left_key
end

#left_modelObject (readonly)

Returns the value of attribute left_model.



7
8
9
# File 'lib/arerd/association.rb', line 7

def left_model
  @left_model
end

#left_side_multiplicityObject (readonly)

Returns the value of attribute left_side_multiplicity.



7
8
9
# File 'lib/arerd/association.rb', line 7

def left_side_multiplicity
  @left_side_multiplicity
end

#right_association_nameObject (readonly)

Returns the value of attribute right_association_name.



7
8
9
# File 'lib/arerd/association.rb', line 7

def right_association_name
  @right_association_name
end

#right_keyObject (readonly)

Returns the value of attribute right_key.



7
8
9
# File 'lib/arerd/association.rb', line 7

def right_key
  @right_key
end

#right_modelObject (readonly)

Returns the value of attribute right_model.



7
8
9
# File 'lib/arerd/association.rb', line 7

def right_model
  @right_model
end

#right_side_multiplicityObject (readonly)

Returns the value of attribute right_side_multiplicity.



7
8
9
# File 'lib/arerd/association.rb', line 7

def right_side_multiplicity
  @right_side_multiplicity
end

Class Method Details

.build(association) ⇒ Object



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
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
103
104
105
106
107
108
109
110
# File 'lib/arerd/association.rb', line 38

def self.build(association)
  case association.macro
  when :has_many
    return if association.options[:through]

    if association.inverse_of.nil?
      warn "Association #{association.name} has no inverse association. Skipping association."

      return
    end

    new(
      left_model: association.active_record,
      left_key: association.active_record_primary_key,
      left_association_name: association.name,
      right_model: association.class_name.constantize,
      right_key: association.foreign_key,
      right_association_name: association.inverse_of.name,
      left_side_multiplicity: association.inverse_of.options[:optional] ? :optional_one : :one,
      right_side_multiplicity: :optional_many
    )
  when :has_one
    return if association.options[:through]

    if association.inverse_of.nil?
      warn "Association #{association.name} has no inverse association. Skipping association."

      return
    end

    new(
      left_model: association.active_record,
      left_key: association.active_record_primary_key,
      left_association_name: association.name,
      right_model: association.class_name.constantize,
      right_key: association.foreign_key,
      right_association_name: association.inverse_of.name,
      left_side_multiplicity: association.inverse_of.options[:optional] ? :optional_one : :one,
      right_side_multiplicity: :optional_one
    )
  when :has_and_belongs_to_many
    if association.inverse_of.nil?
      warn "Association #{association.name} has no inverse association. Skipping association."

      return
    end

    return if association.active_record.name > association.class_name # Avoid duplicate associations

    new(
      left_model: association.active_record,
      left_key: association.active_record_primary_key,
      left_association_name: association.name,
      right_model: association.class_name.constantize,
      right_key: association.foreign_key,
      right_association_name: association.inverse_of.name,
      left_side_multiplicity: :optional_many,
      right_side_multiplicity: :optional_many
    )
  when :belongs_to
    if association.options[:polymorphic]
      warn "Polymorphic associations are not supported yet. Skipping association #{association.name}."

      return
    end

    if association.inverse_of.nil?
      warn "Association #{association.name} has no inverse association."
    end
  else
    warn "Unknown association type: #{association.macro} for #{association.name} in #{left_model.name}"
  end
end

.build_associations_from_models(models) ⇒ Object



112
113
114
115
116
# File 'lib/arerd/association.rb', line 112

def self.build_associations_from_models(models)
  models.flat_map(&:reflect_on_all_associations).map { |association|
    build(association)
  }.compact
end

Instance Method Details

#<=>(other) ⇒ Object



31
32
33
34
35
36
# File 'lib/arerd/association.rb', line 31

def <=>(other)
  return nil unless other.is_a?(Association)

  [left_model.name, right_model.name, left_association_name.to_s, right_association_name.to_s] <=>
    [other.left_model.name, other.right_model.name, other.left_association_name.to_s, other.right_association_name.to_s]
end