Module: SupportTableData

Extended by:
ActiveSupport::Concern
Defined in:
lib/support_table_data.rb,
lib/support_table_data/railtie.rb

Overview

This concern can be mixed into models that represent static support tables. These are small tables that have a limited number of rows, and have values that are often tied to the logic in the code.

The values that should be in support tables can be defined in YAML, JSON, or CSV files. These values can then be synced to the database and helper methods can be generated from them.

Defined Under Namespace

Modules: ClassMethods Classes: Railtie

Class Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Class Attribute Details

.data_directoryString

The directory where data files live by default. If you are running in a Rails environment, then this will be db/support_tables. Otherwise, the current working directory will be used.

Returns:

  • (String)


290
291
292
293
294
295
296
# File 'lib/support_table_data.rb', line 290

def data_directory
  if defined?(@data_directory)
    @data_directory
  elsif defined?(Rails.root)
    Rails.root.join("db", "support_tables").to_s
  end
end

Class Method Details

.support_table_classes(*extra_classes) ⇒ Array<Class>

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Return the list of all support table classes in the order they should be loaded. Note that this method relies on the classes already having been loaded by the application. It can return indeterminate results if eager loading is turned off (i.e. development or test mode in a Rails application).

If any data files exist in the default data directory, any class name that matches the file name will attempt to be loaded (i.e. “task/statuses.yml” will attempt to load the Task::Status class if it exists).

You can also pass in a list of classes that you explicitly want to include in the returned list.

Parameters:

  • extra_classes (Class)

    List of extra classes to include in the return list.

Returns:

  • (Array<Class>)

    List of classes in the order they should be loaded.



330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
# File 'lib/support_table_data.rb', line 330

def support_table_classes(*extra_classes)
  classes = []
  extra_classes.flatten.each do |klass|
    unless klass.is_a?(Class) && klass.include?(SupportTableData)
      raise ArgumentError.new("#{klass} does not include SupportTableData")
    end
    classes << klass
  end

  # Eager load any classes defined in the default data directory by guessing class names
  # from the file names.
  if SupportTableData.data_directory && File.exist?(SupportTableData.data_directory) && File.directory?(SupportTableData.data_directory)
    Dir.chdir(SupportTableData.data_directory) { Dir.glob(File.join("**", "*")) }.each do |file_name|
      class_name = file_name.sub(/\.[^.]*/, "").singularize.camelize
      class_name.safe_constantize
    end
  end

  active_record_classes = ActiveRecord::Base.descendants.reject { |klass| klass.name.nil? }
  active_record_classes.sort_by(&:name).each do |klass|
    next unless klass.include?(SupportTableData)
    next if klass.abstract_class?
    next if classes.include?(klass)
    classes << klass
  end

  levels = [classes]
  checked = Set.new
  loop do
    checked << classes
    dependencies = classes.collect { |klass| support_table_dependencies(klass) }.flatten.uniq.sort_by(&:name)
    break if dependencies.empty? || checked.include?(dependencies)
    levels.unshift(dependencies)
    classes = dependencies
  end

  levels.flatten.uniq
end

.sync_all!(*extra_classes) ⇒ Hash<Class, Array<Hash>] Hash of classes synced with a list of saved changes.

Sync all support table classes. Classes must already be loaded in order to be synced.

You can pass in a list of classes that you want to ensure are synced. This feature can be used to force load classes that are only loaded at runtime. For instance, if eager loading is turned off for the test environment in a Rails application (which is the default), then there is a good chance that support table models won’t be loaded when the test suite is initializing.

Parameters:

  • extra_classes (Class)

    List of classes to force into the detected list of classes to sync.

Returns:

  • (Hash<Class, Array<Hash>] Hash of classes synced with a list of saved changes.)

    Hash<Class, Array<Hash>] Hash of classes synced with a list of saved changes.



308
309
310
311
312
313
314
# File 'lib/support_table_data.rb', line 308

def sync_all!(*extra_classes)
  changes = {}
  support_table_classes(*extra_classes).each do |klass|
    changes[klass] = klass.sync_table_data!
  end
  changes
end

Instance Method Details

#protected_instance?Boolean

Return true if this instance has data being managed from a data file. You can add validation logic using this information if you want to prevent the application from updating protected instances.

Returns:

  • (Boolean)


389
390
391
# File 'lib/support_table_data.rb', line 389

def protected_instance?
  self.class.protected_instance?(self)
end