Class: AnnotateRb::ModelAnnotator::ModelWrapper

Inherits:
Object
  • Object
show all
Defined in:
lib/annotate_rb/model_annotator/model_wrapper.rb

Instance Method Summary collapse

Constructor Details

#initialize(klass, options) ⇒ ModelWrapper

Should be the wrapper for an ActiveRecord model that serves as the source of truth of the model of the model that we’re annotating



9
10
11
12
# File 'lib/annotate_rb/model_annotator/model_wrapper.rb', line 9

def initialize(klass, options)
  @klass = klass
  @options = options
end

Instance Method Details

#classified_sort(cols) ⇒ Object



140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
# File 'lib/annotate_rb/model_annotator/model_wrapper.rb', line 140

def classified_sort(cols)
  rest_cols = []
  timestamps = []
  associations = []
  id = nil

  cols.each do |c|
    if c.name.eql?("id")
      id = c
    elsif c.name.eql?("created_at") || c.name.eql?("updated_at")
      timestamps << c
    elsif c.name[-3, 3].eql?("_id")
      associations << c
    else
      rest_cols << c
    end
  end
  [rest_cols, timestamps, associations].each { |a| a.sort_by!(&:name) }

  ([id] << rest_cols << timestamps << associations).flatten.compact
end

#column_defaultsObject



61
62
63
# File 'lib/annotate_rb/model_annotator/model_wrapper.rb', line 61

def column_defaults
  @klass.column_defaults
end

#columnsObject

Gets the columns of the ActiveRecord model, processes them, and then returns them.



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/annotate_rb/model_annotator/model_wrapper.rb', line 15

def columns
  @columns ||=
    begin
      cols = raw_columns
      cols += translated_columns

      ignore_columns = @options[:ignore_columns]
      if ignore_columns
        cols = cols.reject do |col|
          col.name.match(/#{ignore_columns}/)
        end
      end

      cols = cols.sort_by(&:name) if @options[:sort]
      cols = classified_sort(cols) if @options[:classified_sort]

      cols
    end
end

#connectionObject



35
36
37
# File 'lib/annotate_rb/model_annotator/model_wrapper.rb', line 35

def connection
  @klass.connection
end

#has_table_comments?Boolean

Returns:

  • (Boolean)


56
57
58
59
# File 'lib/annotate_rb/model_annotator/model_wrapper.rb', line 56

def has_table_comments?
  @klass.connection.respond_to?(:table_comment) &&
    @klass.connection.table_comment(@klass.table_name).present?
end

#ignored_translation_table_columnsObject

These are the columns that the globalize gem needs to work but are not necessary for the models to be displayed as annotations.



164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
# File 'lib/annotate_rb/model_annotator/model_wrapper.rb', line 164

def ignored_translation_table_columns
  # Construct the foreign column name in the translations table
  # eg. Model: Car, foreign column name: car_id
  foreign_column_name = [
    @klass.translation_class.to_s
      .gsub("::Translation", "").gsub("::", "_")
      .downcase,
    "_id"
  ].join.to_sym

  [
    :id,
    :created_at,
    :updated_at,
    :locale,
    foreign_column_name
  ]
end

#max_schema_info_widthObject

Calculates the max width of the schema for the model by looking at the columns, schema comments, with respect to the options.



87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/annotate_rb/model_annotator/model_wrapper.rb', line 87

def max_schema_info_width
  @max_schema_info_width ||=
    begin
      cols = columns

      if with_comments?
        column_widths = cols.map do |column|
          column.name.size + (column.comment ? Helper.width(column.comment) : 0)
        end

        max_size = column_widths.max || 0
        max_size += 2
      else
        max_size = cols.map(&:name).map(&:size).max
      end

      max_size += @options[:format_rdoc] ? 5 : 1

      max_size
    end
end

#model_nameObject



81
82
83
# File 'lib/annotate_rb/model_annotator/model_wrapper.rb', line 81

def model_name
  @klass.name.underscore
end

#primary_keyObject



44
45
46
# File 'lib/annotate_rb/model_annotator/model_wrapper.rb', line 44

def primary_key
  @klass.primary_key
end

#raw_columnsObject

Returns the unmodified model columns



40
41
42
# File 'lib/annotate_rb/model_annotator/model_wrapper.rb', line 40

def raw_columns
  @raw_columns ||= @klass.columns
end

#retrieve_indexes_from_tableObject



109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/annotate_rb/model_annotator/model_wrapper.rb', line 109

def retrieve_indexes_from_table
  table_name = @klass.table_name
  return [] unless table_name

  indexes = @klass.connection.indexes(table_name)
  return indexes if indexes.any? || !@klass.table_name_prefix

  # Try to search the table without prefix
  table_name_without_prefix = table_name.to_s.sub(@klass.table_name_prefix, "")
  begin
    @klass.connection.indexes(table_name_without_prefix)
  rescue ActiveRecord::StatementInvalid => _e
    # Mysql2 adapter behaves differently than Sqlite3 and Postgres adapter.
    # If `table_name_without_prefix` does not exist, Mysql2 will raise,
    # the other adapters will return an empty array.
    #
    # See: https://github.com/rails/rails/issues/51205
    []
  end
end

#table_commentsObject



52
53
54
# File 'lib/annotate_rb/model_annotator/model_wrapper.rb', line 52

def table_comments
  @klass.connection.table_comment(@klass.table_name)
end

#table_exists?Boolean

Returns:

  • (Boolean)


48
49
50
# File 'lib/annotate_rb/model_annotator/model_wrapper.rb', line 48

def table_exists?
  @klass.table_exists?
end

#table_nameObject



77
78
79
# File 'lib/annotate_rb/model_annotator/model_wrapper.rb', line 77

def table_name
  @klass.table_name
end

#translated_columnsObject

Add columns managed by the globalize gem if this gem is being used. TODO: Audit if this is still needed, it seems like Globalize gem is no longer maintained



67
68
69
70
71
72
73
74
75
# File 'lib/annotate_rb/model_annotator/model_wrapper.rb', line 67

def translated_columns
  return [] unless @klass.respond_to?(:translation_class)

  ignored_cols = ignored_translation_table_columns

  @klass.translation_class.columns.reject do |col|
    ignored_cols.include? col.name.to_sym
  end
end

#with_comments?Boolean

Returns:

  • (Boolean)


130
131
132
133
134
135
136
137
138
# File 'lib/annotate_rb/model_annotator/model_wrapper.rb', line 130

def with_comments?
  return @with_comments if instance_variable_defined?(:@with_comments)

  @with_comments =
    @options[:with_comment] &&
    @options[:with_column_comments] &&
    raw_columns.first.respond_to?(:comment) &&
    raw_columns.map(&:comment).any? { |comment| !comment.nil? }
end