Class: PermanentRecord

Inherits:
Object
  • Object
show all
Extended by:
ActiveModel::Naming
Defined in:
lib/permanent_record.rb

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(attrs = {}) ⇒ PermanentRecord

Constructs a new PermanentRecord instance. Set instance variable and reader based on input hash.



14
15
16
17
18
19
20
21
# File 'lib/permanent_record.rb', line 14

def initialize attrs={}
  attrs.each do |key, value|
    if valid_attribute? key
      self.instance_variable_set("@#{key}", value) 
      self.class.class_eval{attr_reader key}
    end
  end
end

Class Method Details

.allObject

Returns collection of all PermanentRecord instances.

Example:

>> Model.all
=> [@model1, @model2, ...]


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

def all
  data.map{|d| self.new(d)}
end

.attributesObject

Retrieve or load model attributes.



167
168
169
# File 'lib/permanent_record.rb', line 167

def attributes
  @_attributes ||= attributes_from_data
end

.attributes_from_dataObject

Find attributes based on first data item keys This might be something worth explicitly stating in an ‘attributes’ config or something… but for now I’m going with the lazy way out, and we’ll just check the first data item. So please be sure to have well formed data!



177
178
179
# File 'lib/permanent_record.rb', line 177

def attributes_from_data
  data.first.keys
end

.dataObject

Retrieve or load raw data.



141
142
143
# File 'lib/permanent_record.rb', line 141

def data
  @_data ||= data_from_constant
end

.data_from_constantObject

Auto load data from constant; pluralized model name ie: If your model is called ZooKeeper, this will try and

auto load a constant called ZOO_KEEPERS. You can put that
constant anywhere you want ... like in the model, or in
a constants.rb file, or maybe a zoo_keeprs.rb file.


151
152
153
154
# File 'lib/permanent_record.rb', line 151

def data_from_constant
  data = eval(self.name.to_s.underscore.pluralize.upcase)
  format_data data
end

.find(id) ⇒ Object

Find instance given id. Returns instance if found; nil otherwise.

Example:

>> Model.find(42)
=> @model


54
55
56
# File 'lib/permanent_record.rb', line 54

def find id
  self.find_by_attribute(:id, id)
end

.find_by_attribute(key, value) ⇒ Object

Find instance given attribute name and expected value. Returns instance if found; nil otherwise.

Example:

>> Model.find_by_attribute(:bacon, 'chunky')
=> @model


65
66
67
68
# File 'lib/permanent_record.rb', line 65

def find_by_attribute key, value
  found = data.find{|d| d[key.to_sym].to_s == value.to_s}
  self.new(found) if found
end

.format_data(data) ⇒ Object

Add sequential id to all records. This can be overwritten if an id is specified in the data. CAUTION! If defining your own ids please make sure they’re unique!



160
161
162
163
# File 'lib/permanent_record.rb', line 160

def format_data data
  data = data.each_with_index.map{|d, i| {id: i+1}.merge(d)}
  data.each(&:symbolize_keys!)
end

.method_missing(method, *arguments, &block) ⇒ Object

Oh, just for fun let’s metaprogram some method missing! Provides ‘find_by_<attr>’ finders if you don’t like ‘where’. Returns instance if found; nil otherwise.

Example:

>> Model.find_by_bacon('chunky')
=> @model


91
92
93
94
95
96
97
98
# File 'lib/permanent_record.rb', line 91

def method_missing(method, *arguments, &block)
  match = method.to_s.match(/^find_by_(.*)$/)
  if match && valid_attribute?($1.to_sym)
    find_by_attribute($1.to_sym, arguments.first)
  else
    super
  end
end

.source(data = nil) ⇒ Object

Declares source for PermanentRecord class data. PermanentRecord pretty much just wants to source any ol’ array of hashes. If not declared, it’ll default to a pluralized model name constant. ie: If your model is called MyModel, this’ll try and find MY_MODELS.

The default example, with NO source defined:

class MyModel < PermanentRecord
end

Example with source constant explicitly defined:

class MyModel < PermanentRecord
  source SOME_CONSTANT
end

Another example with a source YAML file explicitly defined:

class MyModel < PermanentRecord
  source YAML.load(File.read('path/to/yaml/file.yml'))
end

I doubt you’d want to define your source as an explicit array of hash, but just to drive home this “any array of hashes” idea here’s an example:

class MyModel < PermanentRecord
  source [{eyes: 'blue', hair: 'blonde'}, {eyes: 'brown', hair: 'green'}]
end


135
136
137
# File 'lib/permanent_record.rb', line 135

def source data=nil
  @_data = format_data data
end

.valid_attribute?(key) ⇒ Boolean

Check if attribute name is valid.

Returns:

  • (Boolean)


183
184
185
# File 'lib/permanent_record.rb', line 183

def valid_attribute? key
  attributes.include?(key)
end

.where(*attrs) ⇒ Object

Find instance(s) given hash of attribute key/values. Returns all instances if found; empty array otherwise.

Example:

>> Model.where(bacon: 'chunky', cats: 'calico')
=> [@model1, @model2, ...]


77
78
79
80
81
# File 'lib/permanent_record.rb', line 77

def where *attrs
  keys = attrs.first.keys
  found = data.map{|d| d if d.reject{|key,_| !keys.include?(key)} == attrs.first}
  found.compact.map{|f| self.new(f)}
end

Instance Method Details

#==(record) ⇒ Object

Overrides equality to match ids.



32
33
34
# File 'lib/permanent_record.rb', line 32

def == record
  self.id == record.try(:id)
end

#to_paramObject

For working with Rails routing helpers. Override in your PermanentRecord class to adjust URLs.



26
27
28
# File 'lib/permanent_record.rb', line 26

def to_param
  self.id
end