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.



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

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.



60
61
62
# File 'lib/rails_erd/domain/relationship.rb', line 60

def destination
  @destination
end

#domainObject (readonly)

The domain in which this relationship is defined.



52
53
54
# File 'lib/rails_erd/domain/relationship.rb', line 52

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.



56
57
58
# File 'lib/rails_erd/domain/relationship.rb', line 56

def source
  @source
end

Class Method Details

.from_associations(domain, associations) ⇒ Object



18
19
20
21
# File 'lib/rails_erd/domain/relationship.rb', line 18

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



143
144
145
# File 'lib/rails_erd/domain/relationship.rb', line 143

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.



77
78
79
# File 'lib/rails_erd/domain/relationship.rb', line 77

def associations
  @forward_associations + @reverse_associations
end

#cardinalityObject

Returns the cardinality of this relationship.



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

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)


95
96
97
# File 'lib/rails_erd/domain/relationship.rb', line 95

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)


133
134
135
# File 'lib/rails_erd/domain/relationship.rb', line 133

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)


102
103
104
# File 'lib/rails_erd/domain/relationship.rb', line 102

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)


127
128
129
# File 'lib/rails_erd/domain/relationship.rb', line 127

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

#recursive?Boolean

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

Returns:

  • (Boolean)


107
108
109
# File 'lib/rails_erd/domain/relationship.rb', line 107

def recursive?
  @source == @destination
end

#strengthObject

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



139
140
141
# File 'lib/rails_erd/domain/relationship.rb', line 139

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)


120
121
122
# File 'lib/rails_erd/domain/relationship.rb', line 120

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)


113
114
115
# File 'lib/rails_erd/domain/relationship.rb', line 113

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