Module: ConstantRecord::DataLoading

Included in:
Base
Defined in:
lib/constant_record.rb

Overview

Loads data either directly in the model class, or from a YAML file.

Instance Method Summary collapse

Instance Method Details

#data(attrib, reload = false) ⇒ Object

Define a constant record: data id: 1, name: “California”, slug: “CA”

Raises:

  • (ArgumentError)


76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/constant_record.rb', line 76

def data(attrib, reload=false)
  raise ArgumentError, "#{self}.data expects a Hash of attributes" unless attrib.is_a?(Hash)
  attrib.symbolize_keys!

  unless attrib[primary_key.to_sym]
    raise ArgumentError, "#{self}.data missing primary key '#{primary_key}': #{attrib.inspect}"
  end

  # Save data definitions for reload on connection change
  @data_rows ||= []

  # Check for duplicates
  unless reload
    if old_record = @data_rows.detect{|r| r[primary_key.to_sym] == attrib[primary_key.to_sym] }
      raise ActiveRecord::RecordNotUnique,
        "Duplicate #{self} id=#{attrib[primary_key.to_sym]} found: #{attrib} vs #{old_record}"
    end
    @data_rows << attrib
  end

  # Create table dynamically based on first row of data
  create_memory_table(attrib) unless connection.table_exists?(table_name)

  # Save to in-memory table
  new_record = new(attrib)
  new_record.id = attrib[primary_key.to_sym]
  new_record.save!

  # Create Ruby constants as well, so "id: 3, name: Sky" generates SKY=3
  if new_record.respond_to?(:name) and name = new_record.name
    const_name =
      name.to_s.upcase.strip.gsub(/[-\s]+/,'_').sub(/^[0-9_]+/,'').gsub(/\W+/,'')
    const_set const_name, new_record.id unless const_defined?(const_name)
  end
end

#data_fileObject



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

def data_file
  @data_file || File.join(ConstantRecord.data_dir, "#{self.to_s.tableize}.yml")
end

#load(reload = false) ⇒ Object



52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/constant_record.rb', line 52

def load(reload=false)
  return if loaded? && !reload
  records = YAML.load_file(data_file)

  if !records.is_a?(Array) or records.empty?
    raise BadDataFile, "Expected array in data file #{data_file}: #{records.inspect}"
  end

  # Call our method to populate data
  @data_rows = []
  records.each{|r| data r}

  @loaded = true
end

#load_data(file = nil) ⇒ Object



47
48
49
50
# File 'lib/constant_record.rb', line 47

def load_data(file=nil)
  @data_file = file
  reload!
end

#loaded?Boolean

Returns:

  • (Boolean)


71
72
73
# File 'lib/constant_record.rb', line 71

def loaded?
  @loaded || false
end

#reload!Object



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

def reload!
  load(true)
end