Module: SupportTableData::ClassMethods

Defined in:
lib/support_table_data.rb

Instance Method Summary collapse

Instance Method Details

#add_support_table_data(data_file_path) ⇒ void

This method returns an undefined value.

Add a data file that contains the support table data. This method can be called multiple times to load data from multiple files.

Parameters:

  • data_file_path (String, Pathname)

    The path to a YAML, JSON, or CSV file containing data for this model. If the path is a relative path, then it will be resolved from the either the default directory set for this model or the global directory set with SupportTableData.data_directory.



60
61
62
63
64
65
# File 'lib/support_table_data.rb', line 60

def add_support_table_data(data_file_path)
  @support_table_data_files ||= []
  root_dir = (support_table_data_directory || SupportTableData.data_directory || Dir.pwd)
  @support_table_data_files << File.expand_path(data_file_path, root_dir)
  define_support_table_named_instances
end

#instance_keysArray

Get the key values for all instances loaded from the data files.

Returns:

  • (Array)

    List of all the key attribute values.



128
129
130
131
132
133
134
135
136
137
138
139
140
141
# File 'lib/support_table_data.rb', line 128

def instance_keys
  unless defined?(@support_table_instance_keys)
    key_attribute = (support_table_key_attribute || primary_key).to_s
    values = []
    support_table_data.each do |attributes|
      key_value = attributes[key_attribute]
      instance = new
      instance.send(:"#{key_attribute}=", key_value)
      values << instance.send(key_attribute)
    end
    @support_table_instance_keys = values.uniq
  end
  @support_table_instance_keys
end

#instance_namesArray<String>

Get the names of all named instances.

Returns:

  • (Array<String>)

    List of all instance names.



120
121
122
123
# File 'lib/support_table_data.rb', line 120

def instance_names
  @support_table_instance_names ||= Set.new
  @support_table_instance_names.to_a
end

#named_instance_attribute_helpers(*attributes) ⇒ void

This method returns an undefined value.

Add class methods to get attributes for named instances. The methods will be named like ‘#instance_name_#attribute_name`. For example, if the name is “active” and the attribute is “id”, then the method will be “active_id” and you can call Model.active_id to get the value.

Parameters:

  • attributes (String, Symbol)

    The names of the attributes to add helper methods for.



74
75
76
77
78
79
80
# File 'lib/support_table_data.rb', line 74

def named_instance_attribute_helpers(*attributes)
  @support_table_attribute_helpers ||= {}
  attributes.flatten.collect(&:to_s).each do |attribute|
    @support_table_attribute_helpers[attribute] = []
  end
  define_support_table_named_instances
end

#protected_instance?(instance) ⇒ Boolean

Return true if the instance has data being managed from a data file.

Returns:

  • (Boolean)


146
147
148
149
150
151
152
153
154
155
# File 'lib/support_table_data.rb', line 146

def protected_instance?(instance)
  key_attribute = (support_table_key_attribute || primary_key).to_s

  unless defined?(@protected_keys)
    keys = support_table_data.collect { |attributes| attributes[key_attribute].to_s }
    @protected_keys = keys
  end

  @protected_keys.include?(instance[key_attribute].to_s)
end

#support_table_attribute_helpersArray<String>

Get the names of any named instance attribute helpers that have been defined with named_instance_attribute_helpers.

Returns:

  • (Array<String>)

    List of attribute names.



86
87
88
89
# File 'lib/support_table_data.rb', line 86

def support_table_attribute_helpers
  @support_table_attribute_helpers ||= {}
  @support_table_attribute_helpers.keys
end

#support_table_dataArray<Hash>

Get the data for the support table from the data files.

Returns:

  • (Array<Hash>)

    List of attributes for all records in the data files.



94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/support_table_data.rb', line 94

def support_table_data
  @support_table_data_files ||= []
  data = {}
  key_attribute = (support_table_key_attribute || primary_key).to_s

  @support_table_data_files.each do |data_file_path|
    file_data = support_table_parse_data_file(data_file_path)
    file_data = file_data.values if file_data.is_a?(Hash)
    file_data = Array(file_data).flatten
    file_data.each do |attributes|
      key_value = attributes[key_attribute].to_s
      existing = data[key_value]
      if existing
        existing.merge!(attributes)
      else
        data[key_value] = attributes
      end
    end
  end

  data.values
end

#sync_table_data!Array<Hash>

Synchronize the rows in the table with the values defined in the data files added with add_support_table_data. Note that rows will not be deleted if they are no longer in the data files.

Returns:

  • (Array<Hash>)

    List of saved changes for each record that was created or modified.



17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/support_table_data.rb', line 17

def sync_table_data!
  return unless table_exists?

  key_attribute = (support_table_key_attribute || primary_key).to_s
  canonical_data = support_table_data.each_with_object({}) { |attributes, hash| hash[attributes[key_attribute].to_s] = attributes }
  records = where(key_attribute => canonical_data.keys)
  changes = []

  ActiveSupport::Notifications.instrument("support_table_data.sync", class: self) do
    transaction do
      records.each do |record|
        key = record[key_attribute].to_s
        attributes = canonical_data.delete(key)
        attributes&.each do |name, value|
          record.send(:"#{name}=", value) if record.respond_to?(:"#{name}=", true)
        end
        if record.changed?
          changes << record.changes
          record.save!
        end
      end

      canonical_data.each_value do |attributes|
        record = new
        attributes.each do |name, value|
          record.send(:"#{name}=", value) if record.respond_to?(:"#{name}=", true)
        end
        changes << record.changes
        record.save!
      end
    end
  end

  changes
end