Module: ApplicationEnumeration

Defined in:
lib/application_enumeration.rb

Overview

Methods for enumerating models, tables, columns etc.

!! If you think that a method belongs here chances are it already exists in a Rails extension.

Note the use of Module.nesting (urbanautomaton.com/blog/2013/08/27/rails-autoloading-hell/)

Class Method Summary collapse

Class Method Details

.all_submodels(klass) ⇒ Array of Classes

!! See the built in self.descendants for actual inheritance tracking, this is path based. Used in Ranks.

Parameters:

  • klass (Object)

Returns:

  • (Array of Classes)

    all models in the /app/models/#klassklass.name (not necessarily inheriting)



76
77
78
# File 'lib/application_enumeration.rb', line 76

def self.all_submodels(klass)
  Dir.glob(Rails.root + "app/models/#{klass.name.underscore}/**/*.rb").collect{|a| self.model_from_file_name(a) }
end

.alternate_value_attributes(object) ⇒ Array

Returns a list symbols that represent populated, non “cached”, non “_id”, non reserved attributes.

Returns:

  • (Array)

    a list symbols that represent populated, non “cached”, non “_id”, non reserved attributes



25
26
27
28
29
30
31
# File 'lib/application_enumeration.rb', line 25

def self.alternate_value_attributes(object)
  if object.class::ALTERNATE_VALUES_FOR.blank?
    raise("#{object.class} attempted to annotate a class without ALTERNATE_VALUES_FOR -  please inform the programmers")
  else
    object.attributes.select{|k,v| v.present? && object.class::ALTERNATE_VALUES_FOR.include?(k.to_sym)}.keys.map(&:to_sym)
  end
end

.annotatable_attributes(object) ⇒ Array of Symbols

!! Some models have blacklists (e.g. Serial)

Parameters:

  • object (Object)

Returns:

  • (Array of Symbols)

    a whitelist of the attributes of a given instance that may be annotated



37
38
39
# File 'lib/application_enumeration.rb', line 37

def self.annotatable_attributes(object)
  object.attributes.select{|k,v| v.present? && !(k =~ /.*_id\z|cached_*.*/)}.keys.map(&:to_sym) - ( RESERVED_ATTRIBUTES - [:parent_id])
end

.attributes(target) ⇒ Array of Symbol

Returns a list attributes except “id”, ‘md5_“, and postfixed ”_id“, ”_at“ This is an arbitrary convention, wrap this to further refine.

Parameters:

Returns:

  • (Array of Symbol)

    a list attributes except “id”, ‘md5_“, and postfixed ”_id“, ”_at“ This is an arbitrary convention, wrap this to further refine.



19
20
21
# File 'lib/application_enumeration.rb', line 19

def self.attributes(target)
   target.attributes.select{|k,v| !(k =~ /\Amd5_|_id\z|\Aid\z|_at\z/)}.symbolize_keys.keys.sort
end

.community_data_classesArray

Returns all superclass models that are community/shared.

Returns:

  • (Array)

    all superclass models that are community/shared



61
62
63
# File 'lib/application_enumeration.rb', line 61

def self.community_data_classes
  superclass_models.select{|a| a < Shared::SharedAcrossProjects }
end

.data_modelsArray

Returns all superclass data models.

Returns:

  • (Array)

    all superclass data models



67
68
69
# File 'lib/application_enumeration.rb', line 67

def self.data_models
  superclass_models.select{|a| a < Shared::IsData}
end

.klass_reflections(klass, relationship_type = :has_many) ⇒ Object

Returns Array of AR associations to access the related class use ‘.klass`.

Returns:

  • Array of AR associations to access the related class use ‘.klass`



98
99
100
101
# File 'lib/application_enumeration.rb', line 98

def self.klass_reflections(klass, relationship_type = :has_many)
  a = klass.reflect_on_all_associations(relationship_type).sort{ |a, b| a.name <=> b.name }
  a
end

.model_from_file_name(file_name) ⇒ Class

e.g. given ‘app/models/specimen.rb’ the Specimen class is returned

Parameters:

  • file_name (String)

Returns:

  • (Class)

    represented by a path included filename from /app/models.



84
85
86
# File 'lib/application_enumeration.rb', line 84

def self.model_from_file_name(file_name)
  file_name.split(/app\/models\//).last[0..-4].split(/\\/).collect{|b| b.camelize}.join('::').safe_constantize
end

.nested_subclasses(parent = self) ⇒ Hash

Parameters:

  • parent (Object) (defaults to: self)

Returns:

  • (Hash)


90
91
92
93
94
# File 'lib/application_enumeration.rb', line 90

def self.nested_subclasses(parent = self)
  parent.subclasses.inject({}) { | hsh, subclass |
    hsh.merge!(subclass.name => nested_subclasses(subclass))
  }
end

.non_project_data_classesArray of Classes

Returns data models that do not have a project_id attribute.

Returns:

  • (Array of Classes)

    data models that do not have a project_id attribute



55
56
57
# File 'lib/application_enumeration.rb', line 55

def self.non_project_data_classes
  data_models - project_data_classes
end

.project_data_classesArray of Classes

Returns all models with a project_id attribute.

Returns:

  • (Array of Classes)

    all models with a project_id attribute



49
50
51
# File 'lib/application_enumeration.rb', line 49

def self.project_data_classes
  superclass_models.select{|a| a.column_names.include?('project_id') }
end

.relation_targets_community?(relation) ⇒ Boolean

Returns:

  • (Boolean)


103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/application_enumeration.rb', line 103

def self.relation_targets_community?(relation)
  case relationship_type(relation)
  when :has_many
    relation.class_name.safe_constantize.is_community?
  when :has_one
    raise TaxonWorks::Error, "Has one support not implemented in unify, throw eggs at the devs."
  when :belongs_to
    if k = relation.options[:class_name]
      k.safe_constantize.is_community?
    else
      raise TaxonWorks::Error, "Missing attribute class_name on #{relation.name}."
    end
  end
end

.relationship_type(relation) ⇒ Object

collection?, has_mone? belongs_to?

Raises:

  • (TaxonWorks::Error)


119
120
121
122
123
124
125
126
127
128
129
# File 'lib/application_enumeration.rb', line 119

def self.relationship_type(relation)
  if relation.collection? # class.name.match('HasMany')
    return :has_many
  elsif relation.has_one? # class.name.match('HasOne')
    return :has_one
  elsif relation.belongs_to? # class.name.match('BelongsTo')
    return :belongs_to
  end

  raise TaxonWorks::Error, "Unknown relationship type for #{relation.name}."
end

.superclass_modelsArray

Returns all models that inherit directly from ApplicationRecord.

Returns:

  • (Array)

    all models that inherit directly from ApplicationRecord



43
44
45
# File 'lib/application_enumeration.rb', line 43

def self.superclass_models
  ApplicationRecord.descendants.select{|a| a.superclass == ApplicationRecord }
end