Class: RailsERD::Domain::Attribute

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

Overview

Describes an entity’s attribute. Attributes correspond directly to database columns.

Constant Summary collapse

TIMESTAMP_NAMES =
%w{created_at created_on updated_at updated_on}

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Inspectable

inspection_attributes

Constructor Details

#initialize(domain, model, column) ⇒ Attribute

Returns a new instance of Attribute.



40
41
42
# File 'lib/rails_erd/domain/attribute.rb', line 40

def initialize(domain, model, column) # @private :nodoc:
  @domain, @model, @column = domain, model, column
end

Instance Attribute Details

#columnObject (readonly)



38
39
40
# File 'lib/rails_erd/domain/attribute.rb', line 38

def column
  @column
end

Class Method Details

.from_model(domain, model) ⇒ Object



12
13
14
15
16
17
18
19
20
21
# File 'lib/rails_erd/domain/attribute.rb', line 12

def from_model(domain, model) # @private :nodoc:
  attributes = model.columns.collect { |column| new(domain, model, column) }
  attributes.sort! if RailsERD.options[:sort]

  if RailsERD.options[:prepend_primary]
    attributes = prepend_primary(model, attributes)
  end

  attributes
end

.prepend_primary(model, attributes) ⇒ Object



23
24
25
26
27
28
29
30
31
32
# File 'lib/rails_erd/domain/attribute.rb', line 23

def prepend_primary(model, attributes)
  primary_key = ActiveRecord::Base.get_primary_key(model)
  primary = attributes.index { |column| column.name == primary_key }

  if primary
    attributes[primary], attributes[0] = attributes[0], attributes[primary]
  end

  attributes
end

Instance Method Details

#<=>(other) ⇒ Object



104
105
106
# File 'lib/rails_erd/domain/attribute.rb', line 104

def <=>(other) # @private :nodoc:
  name <=> other.name
end

#content?Boolean

Returns true if this attribute is a content column, that is, if it is not a primary key, foreign key, timestamp, or inheritance column.

Returns:

  • (Boolean)


57
58
59
# File 'lib/rails_erd/domain/attribute.rb', line 57

def content?
  !primary_key? and !foreign_key? and !timestamp? and !inheritance?
end

#false?Boolean

Method allows false to be set as an attributes option when making custom graphs. It rejects all attributes when called from Diagram#filtered_attributes method

Returns:

  • (Boolean)


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

def false?
  false
end

#foreign_key?Boolean

Returns true if this attribute is used as a foreign key for any relationship.

Returns:

  • (Boolean)


79
80
81
82
83
# File 'lib/rails_erd/domain/attribute.rb', line 79

def foreign_key?
  @domain.relationships_by_entity_name(@model.name).map(&:associations).flatten.map { |associaton|
    associaton.send(Domain.foreign_key_method_name).to_sym
  }.include?(name.to_sym)
end

#inheritance?Boolean

Returns true if this attribute is used for single table inheritance. These attributes are typically named type.

Returns:

  • (Boolean)


87
88
89
# File 'lib/rails_erd/domain/attribute.rb', line 87

def inheritance?
  @model.inheritance_column == name
end

#limitObject

Returns any non-standard limit for this attribute. If a column has no limit or uses a default database limit, this method returns nil.



133
134
135
136
137
# File 'lib/rails_erd/domain/attribute.rb', line 133

def limit
  return if native_type == 'geometry' || native_type == 'geography'
  return column.limit.to_i if column.limit != native_type[:limit] and column.limit.respond_to?(:to_i)
  column.precision.to_i if column.precision != native_type[:precision] and column.precision.respond_to?(:to_i)
end

#limit_descriptionObject

Returns a string that describes the limit for this attribute, such as (128), or (5,2) for decimal types. Returns nil if no non-standard limit was set.



148
149
150
151
# File 'lib/rails_erd/domain/attribute.rb', line 148

def limit_description # @private :nodoc:
  return "(#{limit},#{scale})" if limit and scale
  return "(#{limit})" if limit
end

#mandatory?Boolean

Returns true if this attribute is mandatory. Mandatory attributes either have a presence validation (validates_presence_of), or have a NOT NULL database constraint.

Returns:

  • (Boolean)


64
65
66
# File 'lib/rails_erd/domain/attribute.rb', line 64

def mandatory?
  !column.null or @model.validators_on(name).map(&:kind).include?(:presence)
end

#nameObject

The name of the attribute, equal to the column name.



45
46
47
# File 'lib/rails_erd/domain/attribute.rb', line 45

def name
  column.name
end

#primary_key?Boolean

Returns true if this attribute is the primary key of the entity.

Returns:

  • (Boolean)


73
74
75
# File 'lib/rails_erd/domain/attribute.rb', line 73

def primary_key?
  @model.primary_key.to_s == name.to_s
end

#scaleObject

Returns any non-standard scale for this attribute (decimal types only).



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

def scale
  return column.scale.to_i if column.scale != native_type[:scale] and column.scale.respond_to?(:to_i)
  0 if column.precision
end

#timestamp?Boolean

Returns true if this attribute is one of the standard ‘magic’ Rails timestamp columns, being created_at, updated_at, created_on or updated_on.

Returns:

  • (Boolean)


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

def timestamp?
  TIMESTAMP_NAMES.include? name
end

#to_sObject



108
109
110
# File 'lib/rails_erd/domain/attribute.rb', line 108

def to_s # @private :nodoc:
  name
end

#typeObject

The type of the attribute, equal to the Rails migration type. Can be any of :string, :integer, :boolean, :text, etc.



51
52
53
# File 'lib/rails_erd/domain/attribute.rb', line 51

def type
  column.type or column.sql_type.downcase.to_sym
end

#type_descriptionObject

Returns a description of the attribute type. If the attribute has a non-standard limit or if it is mandatory, this information is included.

Example output:

:integer

integer

:string, :limit => 255

string

:string, :limit => 128

string (128)

<tt>:decimal, :precision => 5, :scale => 2/tt>

decimal (5,2)

:boolean, :null => false

boolean *



121
122
123
124
125
126
127
128
129
# File 'lib/rails_erd/domain/attribute.rb', line 121

def type_description
  type.to_s.dup.tap do |desc|
    desc << " #{limit_description}" if limit_description
    desc << " ∗" if mandatory? && !primary_key? # Add a hair space + low asterisk (Unicode characters)
    desc << " U" if unique? && !primary_key? && !foreign_key? # Add U if unique but non-key
    desc << " PK" if primary_key?
    desc << " FK" if foreign_key?
  end
end

#unique?Boolean

Returns:

  • (Boolean)


68
69
70
# File 'lib/rails_erd/domain/attribute.rb', line 68

def unique?
  @model.validators_on(name).map(&:kind).include?(:uniqueness)
end