Class: Rails::Annotate::Solargraph::Model

Inherits:
Object
  • Object
show all
Defined in:
lib/rails/annotate/solargraph/model.rb

Constant Summary collapse

MAGIC_COMMENT_REGEXP =

Returns:

  • (Regexp)
/(^#\s*encoding:.*(?:\n|r\n))|(^# coding:.*(?:\n|\r\n))|(^# -\*- coding:.*(?:\n|\r\n))|(^# -\*- encoding\s?:.*(?:\n|\r\n))|(^#\s*frozen_string_literal:.+(?:\n|\r\n))|(^# -\*- frozen_string_literal\s*:.+-\*-(?:\n|\r\n))/
TYPE_MAP =

Returns:

  • (Hash{Symbol => String})
{
  float: 'BigDecimal',
  decimal: 'BigDecimal',
  integer: 'Integer',
  datetime: 'ActiveSupport::TimeWithZone',
  date: 'Date',
  string: 'String',
  boolean: 'Boolean',
  text: 'String',
  jsonb: 'Hash',
  citext: 'String',
  json: 'Hash',
  bigint: 'Integer',
  uuid: 'String',
  inet: 'IPAddr'
}

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(klass) ⇒ Model

Returns a new instance of Model.

Parameters:

  • klass (Class)


88
89
90
91
92
93
94
95
96
# File 'lib/rails/annotate/solargraph/model.rb', line 88

def initialize(klass)
  @klass = klass
  @file_name =
    if CONFIG.schema_file?
      SCHEMA_RAILS_PATH
    else
      ::File.join(::Rails.root, MODEL_DIR, "#{klass.to_s.underscore}.rb")
    end
end

Instance Attribute Details

#file_nameString (readonly)

Returns:

  • (String)


82
83
84
# File 'lib/rails/annotate/solargraph/model.rb', line 82

def file_name
  @file_name
end

#klassClass (readonly)

Returns:

  • (Class)


85
86
87
# File 'lib/rails/annotate/solargraph/model.rb', line 85

def klass
  @klass
end

Class Method Details

.add_scope(name, model_class, proc_parameters, definition) ⇒ Object

Parameters:

  • name (Symbol)
  • model_class (Class)
  • proc_parameters (Array<Symbol>)
  • definition (String)


46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/rails/annotate/solargraph/model.rb', line 46

def add_scope(name, model_class, proc_parameters, definition)
  scope = Scope.new(
    name: name,
    model_class: model_class,
    proc_parameters: proc_parameters,
    definition: definition
  )

  @scopes ||= {}
  @scopes[model_class] ||= []
  @scopes[model_class] << scope
  @scopes[model_class].sort_by!(&:name)
end

.annotation_end(klass = nil) ⇒ String

Parameters:

  • klass (Class) (defaults to: nil)

Returns:

  • (String)


69
70
71
72
# File 'lib/rails/annotate/solargraph/model.rb', line 69

def annotation_end(klass = nil)
  table_name = klass && CONFIG.schema_file? ? ":#{klass.table_name}" : ''
  "%%<RailsAnnotateSolargraph:End#{table_name}>%%\n\n"
end

.annotation_regexp(klass = nil) ⇒ Regexp

Parameters:

  • klass (Class) (defaults to: nil)

Returns:

  • (Regexp)


76
77
78
# File 'lib/rails/annotate/solargraph/model.rb', line 76

def annotation_regexp(klass = nil)
  /#{annotation_start(klass)}.*#{annotation_end(klass)}/m
end

.annotation_start(klass = nil) ⇒ String

Parameters:

  • klass (Class) (defaults to: nil)

Returns:

  • (String)


62
63
64
65
# File 'lib/rails/annotate/solargraph/model.rb', line 62

def annotation_start(klass = nil)
  table_name = klass && CONFIG.schema_file? ? ":#{klass.table_name}" : ''
  "\n# %%<RailsAnnotateSolargraph:Start#{table_name}>%%"
end

.scopesHash{Class => Array<Rails::Annotate::Solargraph::Model::Scope>}

Returns:

  • (Hash{Class => Array<Rails::Annotate::Solargraph::Model::Scope>})


37
38
39
40
# File 'lib/rails/annotate/solargraph/model.rb', line 37

def scopes
  @scopes ||= {}
  @scopes
end

Instance Method Details

#annotate(write: true) ⇒ String

Returns New file content.

Parameters:

  • write (Boolean) (defaults to: true)

Returns:

  • (String)

    New file content.



115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'lib/rails/annotate/solargraph/model.rb', line 115

def annotate(write: true)
  old_content, file_content = remove_annotation write: false
  return old_content if @klass.abstract_class

  if CONFIG.annotation_position == :top
    magic_comments = file_content.scan(MAGIC_COMMENT_REGEXP).flatten.compact.join
    file_content.sub!(MAGIC_COMMENT_REGEXP, '')

    new_file_content = magic_comments + annotation + file_content
  else
    new_file_content = file_content + annotation
  end

  return new_file_content unless write
  return new_file_content if old_content == new_file_content

  write_file @file_name, new_file_content
  new_file_content
end

#annotationString

Returns:

  • (String)


151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
# File 'lib/rails/annotate/solargraph/model.rb', line 151

def annotation
  doc_string = ::String.new
  doc_string << <<~DOC
    #{annotation_start}
    ##{parse_clause}
    #   class #{@klass} < #{@klass.superclass}
  DOC

  document_scopes(doc_string)
  document_relations(doc_string)
  document_fields(doc_string)

  doc_string << <<~DOC.chomp
    #   end
    # #{annotation_end}
  DOC

  # uncomment the generated annotations if they're saved in the schema file
  return doc_string.gsub(/^#\ {3}/, '').gsub(/^#\n/, "\n") if CONFIG.schema_file?

  doc_string
end

#annotation_endString

Returns:

  • (String)


104
105
106
# File 'lib/rails/annotate/solargraph/model.rb', line 104

def annotation_end
  self.class.annotation_end(@klass)
end

#annotation_regexpRegexp

Returns:

  • (Regexp)


109
110
111
# File 'lib/rails/annotate/solargraph/model.rb', line 109

def annotation_regexp
  self.class.annotation_regexp(@klass)
end

#annotation_startString

Returns:

  • (String)


99
100
101
# File 'lib/rails/annotate/solargraph/model.rb', line 99

def annotation_start
  self.class.annotation_start(@klass)
end

#remove_annotation(write: true) ⇒ Array<String>

Returns Old file content followed by new content.

Parameters:

  • write (Boolean) (defaults to: true)

Returns:

  • (Array<String>)

    Old file content followed by new content.



137
138
139
140
141
142
143
144
145
146
147
148
# File 'lib/rails/annotate/solargraph/model.rb', line 137

def remove_annotation(write: true)
  return ['', ''] unless ::File.exist?(@file_name)

  file_content = ::File.read(@file_name)
  new_file_content = file_content.sub(annotation_regexp, '')
  result = [file_content, new_file_content]
  return result unless write
  return result if file_content == new_file_content

  write_file @file_name, new_file_content
  result
end