class ArrayModel

ArrayModel

This is used as a base class to create ActiveRecord / Sequel style models from simple arrays and hashes. This is useful for integrating simple reference data into an ActiveRecord model without having to create many small tables that will never change.

This data should be never change while the application is running, so the model objects that are created are read only. The data can come either from a constant in the ruby script itself, or from the filesystem as a YAML or JSON file.

Example:

USERS = [
   { name: 'Nathan', year: 1984 }, 
   { name: 'Dave', year: 1987 }
]

class User < ArrayModel
   model_data USERS
   attr_model_reader :name
   attr_model_reader :year

   def age
           Time.now.year - year
   end
end

User[0].age # => 32
User[1].name # => "Dave"

Constants

VERSION

Public Class Methods

[](k) click to toggle source

get the object with the key :k:

By default :k: will be a simple array index, but it can be changed to any field by using the :primary_key option when calling :model_data: when the class is defined

Users['reednj'] # => #<Users:0x007fe693866808>
# File lib/array_model.rb, line 44
def self.[](k)
        if @data_key.nil?
                item_data = @data[k.to_i]
        else
                # if a key has been specified, then find the first matching
                # record. It would be faster to convert it to a hash, but since the
                # number of records should be small, this should do for now
                item_data = @data.select{|a| a[@data_key] == k }.first
        end

        return nil if item_data.nil?
        return self.new(item_data)
end
all() click to toggle source

returns an array of all the data in the model. The array will contain objects of the appropriate type (not raw hashes)

# File lib/array_model.rb, line 60
def self.all
        if @data.is_a? Array
                @all_records ||= @data.map { |v| self.new(v) }
        else
                raise "ArrayModel does not support #{@data.class} as data source"
        end           
end
attr_model_reader(name, options = {}) click to toggle source

Adds attr_reader methods to the class for a given field in the data hash. The :key: option can be used to set the name of the key in the hash, if it doesn’t have the same name as the method

class Users < ArrayModel
  ...
  attr_model_reader :username
  attr_model_reader :user_id, :key => :userId
  ...
end
# File lib/array_model.rb, line 111
def self.attr_model_reader(name, options = {})
        define_method name.to_sym do
                values[(options[:key] || name).to_sym]
        end
end
attr_model_readers(keys) click to toggle source

like :attr_model_reader:, but mulitple readers can be added at once. No options can be passed when using this method to add the readers

class Users < ArrayModel
  ...
      attr_model_readers [:username, :user_id]
  ...
end
# File lib/array_model.rb, line 127
def self.attr_model_readers(keys)
        keys.each {|k| attr_model_reader k }
end
model_data(data, options = nil) click to toggle source

add the model data to the model class. This data should be in the from of an array of hashes.

The array model is designed to handle static reference data, so the data should not change while the application is running. It can come either from a constant hard coded into the ruby file, or from a json or yaml file on the filesystem.

The :primary_key option can be used to index the data by a particular field in the hash when it is accessed later via the subscript operator. If this option is ommited then the data will be accessable simply by the array index

class Users < ArrayModel
  # USER_LIST is a const containing an array of hashes
  model_data USER_LIST, :primary_key => :username
  ...
end
# File lib/array_model.rb, line 149
def self.model_data(data, options = nil)
        options ||= {}
        data.is_a! Array, 'data'

        @data_key = options[:primary_key]
        @data = data  
end
new(item_data) click to toggle source

create a new model object from a given hash. This should never need to be called directly - the class methods should be used to get model objects from the dataset

# File lib/array_model.rb, line 94
def initialize(item_data)
        item_data.is_a! Hash, 'item_data'
        @item_data = item_data
end

Public Instance Methods

[](k) click to toggle source

an alias for the values method to return a raw value from the data hash for a given model object. The attr_reader methods should be prefered to accessing the hash directly, but this can be useful in certain cases

u = Users['reednj']
u.username                        # => 'reednj'
u.values(:username)       # => 'reednj'
u[:username]                      # => 'reednj'
# File lib/array_model.rb, line 78
def [](k)
        values[k]
end
values() click to toggle source

returns the raw Hash that provides the data for the model object

Users['reednj'].values # => {:username => 'reednj', ...}
# File lib/array_model.rb, line 87
def values
        @item_data
end