Class: RailsERD::Domain::Relationship

Inherits:
Object
  • Object
show all
Extended by:
Inspectable
Defined in:
lib/rails_erd/domain/relationship.rb,
lib/rails_erd/domain/relationship/cardinality.rb

Overview

Describes a relationship between two entities. A relationship is detected based on Active Record associations. One relationship may represent more than one association, however. Related associations are grouped together. Associations are related if they share the same foreign key, or the same join table in the case of many-to-many associations.

Defined Under Namespace

Classes: Cardinality

Constant Summary collapse

N =
Cardinality::N

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Inspectable

inspection_attributes

Constructor Details

#initialize(domain, associations) ⇒ Relationship

Returns a new instance of Relationship.



63
64
65
66
67
68
69
70
71
# File 'lib/rails_erd/domain/relationship.rb', line 63

def initialize(domain, associations) # @private :nodoc:
  @domain = domain
  @reverse_associations, @forward_associations = partition_associations(associations)

  assoc = @forward_associations.first || @reverse_associations.first
  @source      = @domain.entity_by_name(self.class.send(:association_owner, assoc))
  @destination = @domain.entity_by_name(self.class.send(:association_target, assoc))
  @source, @destination = @destination, @source if assoc.belongs_to?
end

Instance Attribute Details

#destinationObject (readonly)

The destination entity. It corresponds to the model that has defined a belongs_to association with the other model.



58
59
60
# File 'lib/rails_erd/domain/relationship.rb', line 58

def destination
  @destination
end

#domainObject (readonly)

The domain in which this relationship is defined.



50
51
52
# File 'lib/rails_erd/domain/relationship.rb', line 50

def domain
  @domain
end

#sourceObject (readonly)

The source entity. It corresponds to the model that has defined a has_one or has_many association with the other model.



54
55
56
# File 'lib/rails_erd/domain/relationship.rb', line 54

def source
  @source
end

Class Method Details

.from_associations(domain, associations) ⇒ Object



16
17
18
19
# File 'lib/rails_erd/domain/relationship.rb', line 16

def from_associations(domain, associations) # @private :nodoc:
  assoc_groups = associations.group_by { |assoc| association_identity(assoc) }
  assoc_groups.collect { |_, assoc_group| new(domain, assoc_group.to_a) }
end

Instance Method Details

#<=>(other) ⇒ Object



141
142
143
# File 'lib/rails_erd/domain/relationship.rb', line 141

def <=>(other) # @private :nodoc:
  (source.name <=> other.source.name).nonzero? or (destination.name <=> other.destination.name)
end

#associationsObject

Returns all Active Record association objects that describe this relationship.



75
76
77
# File 'lib/rails_erd/domain/relationship.rb', line 75

def associations
  @forward_associations + @reverse_associations
end

#cardinalityObject

Returns the cardinality of this relationship.



80
81
82
83
84
85
86
87
# File 'lib/rails_erd/domain/relationship.rb', line 80

def cardinality
  @cardinality ||= begin
    reverse_max = any_habtm?(associations) ? N : 1
    forward_range = associations_range(@forward_associations, N)
    reverse_range = associations_range(@reverse_associations, reverse_max)
    Cardinality.new(reverse_range, forward_range)
  end
end

#indirect?Boolean

Indicates if a relationship is indirect, that is, if it is defined through other relationships. Indirect relationships are created in Rails with has_many :through or has_one :through association macros.

Returns:

  • (Boolean)


93
94
95
# File 'lib/rails_erd/domain/relationship.rb', line 93

def indirect?
  !@forward_associations.empty? and @forward_associations.all?(&:through_reflection)
end

#many_to?Boolean

Indicates whether the source cardinality class of this relationship is equal to infinity. This is true for many-to-many relationships only.

Returns:

  • (Boolean)


131
132
133
# File 'lib/rails_erd/domain/relationship.rb', line 131

def many_to?
  cardinality.cardinality_class[0] != 1
end

#mutual?Boolean

Indicates whether or not the relationship is defined by two inverse associations (e.g. a has_many and a corresponding belongs_to association).

Returns:

  • (Boolean)


100
101
102
# File 'lib/rails_erd/domain/relationship.rb', line 100

def mutual?
  @forward_associations.any? and @reverse_associations.any?
end

#one_to?Boolean

Indicates whether the source cardinality class of this relationship is equal to one. This is true for one-to-one or one-to-many relationships only.

Returns:

  • (Boolean)


125
126
127
# File 'lib/rails_erd/domain/relationship.rb', line 125

def one_to?
  cardinality.cardinality_class[0] == 1
end

#recursive?Boolean

Indicates whether or not this relationship connects an entity with itself.

Returns:

  • (Boolean)


105
106
107
# File 'lib/rails_erd/domain/relationship.rb', line 105

def recursive?
  @source == @destination
end

#strengthObject

The strength of a relationship is equal to the number of associations that describe it.



137
138
139
# File 'lib/rails_erd/domain/relationship.rb', line 137

def strength
  if source.generalized? then 1 else associations.size end
end

#to_many?Boolean

Indicates whether the destination cardinality class of this relationship is equal to infinity. This is true for one-to-many or many-to-many relationships only.

Returns:

  • (Boolean)


118
119
120
# File 'lib/rails_erd/domain/relationship.rb', line 118

def to_many?
  cardinality.cardinality_class[1] != 1
end

#to_one?Boolean

Indicates whether the destination cardinality class of this relationship is equal to one. This is true for one-to-one relationships only.

Returns:

  • (Boolean)


111
112
113
# File 'lib/rails_erd/domain/relationship.rb', line 111

def to_one?
  cardinality.cardinality_class[1] == 1
end