module Muve::Model
Muve
models imitate some behavior that one may commonly expect of typical models. There are mechanisms in place for creation, modification, retrieval and the removal of resources.
In order to make this a flexible solution, models never take care of handling the persisting of the resources they manange. That part of the lifing is dispatched to the Model::Store
object which may be though of as an adaptor.
– TODO: Include ActiveRecord::Model instead of using this tedious implementation ++
Public Class Methods
Connection to the datastore
# File lib/muve.rb, line 48 def self.connection begin @@conn rescue => e raise NotConfigured, "the connection has not been defined" end end
Set the connection to the datastore
# File lib/muve.rb, line 39 def self.connection=connection (@@conn = connection) if (connection) end
Database instance to be used by the adaptor
# File lib/muve.rb, line 57 def self.database begin @@db rescue => e raise NotConfigured, "the database has not been defined" end end
# File lib/muve.rb, line 43 def self.database=database (@@db = database) if (database) end
# File lib/muve/model.rb, line 50 def self.handler @handler end
# File lib/muve/model.rb, line 35 def self.included(base) base.extend ClassMethods end
Initializes the Muve::Model
class. Use the Muve::Model::init
method to set a adaptor to take care of the retrieval and storage of resources.
# File lib/muve/model.rb, line 46 def self.init(handler=nil) @handler = handler if handler end
# File lib/muve/model.rb, line 19 def initialize(params={}) params = {} unless params params.each do |attr, value| next if invalid_attributes.include? attr.to_s self.public_send "#{attr}=", value end @new_record = true @destroyed = false end
Public Instance Methods
# File lib/muve/model.rb, line 39 def ==(rival) return false unless rival.kind_of? self.class self.attributes == rival.attributes end
Returns a Hash of the attributes for the current resource.
# File lib/muve/model.rb, line 141 def attributes self.class.extract_attributes( resource: self, fields: fields, invalid_attributes: invalid_attributes, id: self.id ) end
# File lib/muve/model.rb, line 135 def attributes=(data) Helper.symbolize_keys(data).each { |k, v| self.public_send("#{k}=", v) } self end
Connection to the datastore
# File lib/muve.rb, line 29 def connection Model.connection end
Database instance for the model
# File lib/muve.rb, line 34 def database Model.database end
Destroy a resource
# File lib/muve/model.rb, line 92 def destroy if adaptor.delete(self.class, id) == true @destroyed = true end end
Returns true if the resource in question has been destroyed
# File lib/muve/model.rb, line 112 def destroyed? @destroyed end
# File lib/muve/model.rb, line 126 def id @id end
Returns true if the resource fails any validation
# File lib/muve/model.rb, line 122 def invalid? !valid? end
Returns true if the resource has recently been instantiated but not yet written to the data store.
# File lib/muve/model.rb, line 100 def new_record? @new_record = true if @new_record.nil? @new_record end
Returns true if the resource is not newly instantiated or recently destroyed.
# File lib/muve/model.rb, line 107 def persisted? !(new_record? || destroyed?) end
# File lib/muve/model.rb, line 30 def reload self.send(:populate, extract(adaptor.get(self.class, id), self.class)) if id self end
Save a resource
# File lib/muve/model.rb, line 84 def save # TODO: be more verbose about the nature of the failure, if any (create_or_update if valid?) or false rescue => e false end
Save a resource and raises an SaveError on failure
# File lib/muve/model.rb, line 76 def save! raise ValidationError, "validation failed" unless valid? create_or_update rescue => e raise SaveError, "Save failed because #{e} was raised" end
Returns a hash of the object and subsequently containing objects that respond to to_hash
. In order to avoid circular reference hell you can set the limit.
By default on the the root object and its children a explored. Everything beyond that range is discarded.
# File lib/muve/model.rb, line 62 def to_hash(level=0, limit=1) hash = {} attributes.map { |k, v| if v.respond_to? :to_hash (hash[k.to_sym] = v.to_hash(level+1, limit)) if level < limit else #(raise AssocError, "#Associated #{v.class} for #{k} must respond to #to_hash or be a Hash") unless v.kind_of? Hash hash[k.to_sym] = v end } hash end
The parameterized identifier of the resource
# File lib/muve/model.rb, line 131 def to_param id && id.to_s end
Returns a true if the resource passes all validations
# File lib/muve/model.rb, line 117 def valid? false end
Private Instance Methods
# File lib/muve/model.rb, line 201 def adaptor self.class.adaptor end
# File lib/muve/model.rb, line 209 def convert(resource) self.class.convert(resource) end
Creates the record and performs the necessary housekeeping (e.g.: setting the new id and un-marking the new_record?
# File lib/muve/model.rb, line 190 def create(attr) @id = adaptor.create(self.class, attr) # TODO: deal with unsuccessful #create @new_record = false end
# File lib/muve/model.rb, line 176 def create_or_update result = new_record? ? create(storeable_attributes) : update(storeable_attributes) self end
# File lib/muve/model.rb, line 205 def extract(storeable, klass=nil) self.class.extract(storeable, klass) end
A manifest of the fields known to the model. The model logic seeks counsel from this resource to determine which properties to write and read from the repository.
# File lib/muve/model.rb, line 184 def fields [] end
Reserved attributes. These keys are not available to the user because they are used to handle plumbing (library internal operations).
# File lib/muve/model.rb, line 153 def invalid_attributes %w(id adaptor) end
# File lib/muve/model.rb, line 157 def populate(details) details = {} unless details @id = details[:id] if details.key? :id details.each do |attr, value| next if invalid_attributes.include? attr.to_s self.public_send "#{attr}=", value if fields.include? attr.to_sym end @new_record = false if details.key? :id end
# File lib/muve/model.rb, line 170 def storeable_attributes hash = {} attributes.map { |k, v| hash[k] = convert(v) } hash end
TODO: Update the record and return the number of modified rows
# File lib/muve/model.rb, line 197 def update(attr) adaptor.update(self.class, id, attr) end