memory_model 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +17 -0
- data/.rspec +2 -0
- data/.travis.yml +6 -0
- data/Gemfile +4 -0
- data/Guardfile +5 -0
- data/LICENSE.txt +22 -0
- data/README.md +31 -0
- data/Rakefile +1 -0
- data/lib/concerned_inheritance/class_methods.rb +28 -0
- data/lib/concerned_inheritance/delegator.rb +21 -0
- data/lib/concerned_inheritance/module_methods.rb +11 -0
- data/lib/concerned_inheritance.rb +27 -0
- data/lib/memory_model/base/actionable.rb +95 -0
- data/lib/memory_model/base/attributable.rb +76 -0
- data/lib/memory_model/base/collectable.rb +22 -0
- data/lib/memory_model/base/comparable.rb +16 -0
- data/lib/memory_model/base/fieldable/field.rb +35 -0
- data/lib/memory_model/base/fieldable/field_set.rb +74 -0
- data/lib/memory_model/base/fieldable.rb +45 -0
- data/lib/memory_model/base/persistence.rb +15 -0
- data/lib/memory_model/base/versionable.rb +17 -0
- data/lib/memory_model/base.rb +51 -0
- data/lib/memory_model/collection.rb +80 -0
- data/lib/memory_model/core_ext/object.rb +5 -0
- data/lib/memory_model/version.rb +3 -0
- data/lib/memory_model.rb +13 -0
- data/memory_model.gemspec +30 -0
- data/spec/concerned_inheritance/class_methods_spec.rb +57 -0
- data/spec/concerned_inheritance/delegator_spec.rb +52 -0
- data/spec/concerned_inheritance/module_methods_spec.rb +27 -0
- data/spec/memory_model/base/actionable_spec.rb +359 -0
- data/spec/memory_model/base/attributable_spec.rb +143 -0
- data/spec/memory_model/base/collectable_spec.rb +24 -0
- data/spec/memory_model/base/comparable_spec.rb +155 -0
- data/spec/memory_model/base/fieldable/field_set_spec.rb +160 -0
- data/spec/memory_model/base/fieldable/field_spec.rb +96 -0
- data/spec/memory_model/base/fieldable_spec.rb +23 -0
- data/spec/memory_model/base/persistence_spec.rb +37 -0
- data/spec/memory_model/base/versionable_spec.rb +31 -0
- data/spec/memory_model/base_spec.rb +52 -0
- data/spec/memory_model/collection_spec.rb +216 -0
- data/spec/memory_model/concerned_inheritance_spec.rb +24 -0
- data/spec/memory_model/core_ext/object_spec.rb +12 -0
- data/spec/spec_helper.rb +12 -0
- data/spec/support/active_model_lint.rb +16 -0
- metadata +253 -0
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/Guardfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Jason Waldrip
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
[![Build Status](https://travis-ci.org/jwaldrip/memory_model.png?branch=master)](https://travis-ci.org/jwaldrip/memory_model)
|
2
|
+
|
3
|
+
# MemoryModel
|
4
|
+
|
5
|
+
TODO: Write a gem description
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
gem 'memory_model'
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install memory_model
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
|
23
|
+
TODO: Write usage instructions here
|
24
|
+
|
25
|
+
## Contributing
|
26
|
+
|
27
|
+
1. Fork it
|
28
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
29
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
30
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
31
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module ConcernedInheritance::ClassMethods
|
2
|
+
|
3
|
+
def inherited_callbacks
|
4
|
+
(self.singleton_class.ancestors + self.ancestors).select do |ancestor|
|
5
|
+
ancestor.instance_variable_defined? :@inherited_callbacks
|
6
|
+
end.map do |ancestor|
|
7
|
+
ancestor.instance_variable_get :@inherited_callbacks
|
8
|
+
end.flatten
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def inherited(subclass=nil, &block)
|
14
|
+
if subclass.nil?
|
15
|
+
define_inherited_callback(&block)
|
16
|
+
else
|
17
|
+
run_inherited_callbacks(subclass)
|
18
|
+
super(subclass)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def run_inherited_callbacks(subclass)
|
23
|
+
self.inherited_callbacks.each do |callback|
|
24
|
+
ConcernedInheritance::Delegator.new(self, subclass, callback)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
class ConcernedInheritance::Delegator < BasicObject
|
2
|
+
|
3
|
+
attr_reader :baseclass, :subclass
|
4
|
+
|
5
|
+
def initialize(baseclass, subclass, callback)
|
6
|
+
@baseclass = baseclass
|
7
|
+
@subclass = subclass
|
8
|
+
if callback.not_a?(::Proc)
|
9
|
+
raise ::ArgumentError, "#{callback} must be a proc"
|
10
|
+
elsif (-1..0).cover?(callback.arity)
|
11
|
+
instance_eval(&callback)
|
12
|
+
else
|
13
|
+
raise ::ArgumentError, "#{callback} must have an arity of 0, got #{callback.arity}"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def method_missing(m, *args, &block)
|
18
|
+
subclass.send m, *args, &block
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'active_support/concern'
|
2
|
+
require 'active_support/core_ext/class/attribute'
|
3
|
+
require 'active_support/dependencies/autoload'
|
4
|
+
|
5
|
+
module ConcernedInheritance
|
6
|
+
extend ActiveSupport::Autoload
|
7
|
+
|
8
|
+
autoload :Delegator
|
9
|
+
autoload :ClassMethods
|
10
|
+
autoload :ModuleMethods
|
11
|
+
|
12
|
+
def self.extended(base)
|
13
|
+
case base
|
14
|
+
when Class
|
15
|
+
base.extend ClassMethods
|
16
|
+
when Module
|
17
|
+
base.extend ModuleMethods
|
18
|
+
end
|
19
|
+
base.instance_variable_set :@inherited_callbacks, [] unless base.instance_variable_defined? :@inherited_callbacks
|
20
|
+
end
|
21
|
+
|
22
|
+
def define_inherited_callback(&block)
|
23
|
+
raise ArgumentError, 'missing required block' unless block_given?
|
24
|
+
@inherited_callbacks += [block]
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
require 'ice_nine'
|
2
|
+
require 'ice_nine/core_ext/object'
|
3
|
+
|
4
|
+
module MemoryModel::Base::Actionable
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
included do
|
8
|
+
define_model_callbacks :create, :update, :save, :destroy
|
9
|
+
attr_reader :timestamp
|
10
|
+
end
|
11
|
+
|
12
|
+
VALID_IVARS = [
|
13
|
+
:@deleted,
|
14
|
+
:@attributes,
|
15
|
+
:@timestamp,
|
16
|
+
:@version
|
17
|
+
]
|
18
|
+
|
19
|
+
def commit
|
20
|
+
@timestamp = Time.now
|
21
|
+
@version = SecureRandom.hex(6)
|
22
|
+
self.class.insert self
|
23
|
+
self
|
24
|
+
end
|
25
|
+
|
26
|
+
def delete
|
27
|
+
@deleted = true
|
28
|
+
commit
|
29
|
+
freeze
|
30
|
+
end
|
31
|
+
|
32
|
+
def deleted?
|
33
|
+
!!@deleted
|
34
|
+
end
|
35
|
+
|
36
|
+
def deleted_at
|
37
|
+
deleted? ? @timestamp : nil
|
38
|
+
end
|
39
|
+
|
40
|
+
def destroy
|
41
|
+
run_callbacks :destroy do
|
42
|
+
delete
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def dup
|
47
|
+
deep_dup
|
48
|
+
end
|
49
|
+
|
50
|
+
def deep_dup
|
51
|
+
Marshal.load Marshal.dump self
|
52
|
+
end
|
53
|
+
|
54
|
+
def freeze
|
55
|
+
instance_variables.reject { |ivar| ivar.in? VALID_IVARS }.each do |ivar|
|
56
|
+
remove_instance_variable ivar if instance_variable_defined?(ivar)
|
57
|
+
end
|
58
|
+
instance_variables.each { |ivar| instance_variable_get(ivar).freeze }
|
59
|
+
deep_freeze
|
60
|
+
super
|
61
|
+
end
|
62
|
+
|
63
|
+
def save
|
64
|
+
callback = persisted? ? :update : :create
|
65
|
+
run_callbacks callback do
|
66
|
+
run_callbacks :save do
|
67
|
+
commit
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def restore
|
73
|
+
instance = frozen? ? self.dup : self
|
74
|
+
instance.instance_variable_set :@deleted, false
|
75
|
+
instance.save
|
76
|
+
instance
|
77
|
+
end
|
78
|
+
|
79
|
+
module ClassMethods
|
80
|
+
|
81
|
+
def create(attributes={})
|
82
|
+
new(attributes).save
|
83
|
+
end
|
84
|
+
|
85
|
+
def delete_all
|
86
|
+
all.map(&:delete).reject(&:deleted?).empty?
|
87
|
+
end
|
88
|
+
|
89
|
+
def destroy_all
|
90
|
+
all.map(&:destroy).reject(&:deleted?).empty?
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
module MemoryModel::Base::Attributable
|
2
|
+
extend ActiveSupport::Concern
|
3
|
+
include ActiveModel::AttributeMethods
|
4
|
+
include ActiveModel::Dirty
|
5
|
+
|
6
|
+
included do
|
7
|
+
attr_reader :attributes
|
8
|
+
delegate :to_hash, to: :attributes
|
9
|
+
attribute_method_affix :prefix => 'reset_', :suffix => '_to_default!'
|
10
|
+
attribute_method_prefix 'clear_'
|
11
|
+
end
|
12
|
+
|
13
|
+
def has_attribute?(key)
|
14
|
+
case value = @attributes[key]
|
15
|
+
when NilClass, String
|
16
|
+
!value.nil?
|
17
|
+
else
|
18
|
+
value.present?
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def inspect
|
23
|
+
inspection = if @attributes
|
24
|
+
fields.reduce([]) { |array, name|
|
25
|
+
array << "#{name}: #{attribute_for_inspect(name)}" if has_attribute?(name)
|
26
|
+
array
|
27
|
+
}.join(", ")
|
28
|
+
else
|
29
|
+
"not initialized"
|
30
|
+
end
|
31
|
+
"#<#{[self.class, inspection].join(' ')}>"
|
32
|
+
end
|
33
|
+
|
34
|
+
def read_attribute(name)
|
35
|
+
@attributes[name]
|
36
|
+
end
|
37
|
+
|
38
|
+
alias :[] :read_attribute
|
39
|
+
|
40
|
+
def write_attribute(name, value)
|
41
|
+
raise MemoryModel::InvalidFieldError,
|
42
|
+
"#{name} is not a valid field" unless fields.include? name
|
43
|
+
raise MemoryModel::FieldReadOnlyError,
|
44
|
+
"#{name} is read only" if fields[name].options[:readonly]
|
45
|
+
|
46
|
+
send "#{name}_will_change!" unless value == read_attribute(name) || new_record?
|
47
|
+
@attributes[name] = value
|
48
|
+
end
|
49
|
+
|
50
|
+
alias :[]= :write_attribute
|
51
|
+
|
52
|
+
protected
|
53
|
+
|
54
|
+
def attribute_for_inspect(attr_name)
|
55
|
+
value = read_attribute(attr_name)
|
56
|
+
|
57
|
+
if value.is_a?(String) && value.length > 50
|
58
|
+
"#{value[0..50]}...".inspect
|
59
|
+
elsif value.is_a?(Date) || value.is_a?(Time)
|
60
|
+
value.to_s
|
61
|
+
else
|
62
|
+
value.inspect
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
private
|
67
|
+
|
68
|
+
def reset_attribute_to_default!(attr)
|
69
|
+
write_attribute attr, fields.default_values(self).with_indifferent_access[attr]
|
70
|
+
end
|
71
|
+
|
72
|
+
def clear_attribute(attr)
|
73
|
+
write_attribute attr, nil
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'active_support/concern'
|
2
|
+
|
3
|
+
module MemoryModel::Base::Collectable
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
extend ConcernedInheritance
|
6
|
+
|
7
|
+
inherited do
|
8
|
+
instance_variable_set :@collection, baseclass.collection
|
9
|
+
end
|
10
|
+
|
11
|
+
module ClassMethods
|
12
|
+
delegate :all, :find, :insert, :<<, :deleted, to: :collection
|
13
|
+
delegate :first, :last, to: :all
|
14
|
+
|
15
|
+
def collection
|
16
|
+
return nil if self == MemoryModel::Base
|
17
|
+
@collection ||= MemoryModel::Collection.new(self)
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module MemoryModel::Base::Comparable
|
2
|
+
|
3
|
+
def ==(other_object)
|
4
|
+
attributes.slice(*fields.comparable) ==
|
5
|
+
other_object.to_hash.with_indifferent_access.slice(*fields.comparable)
|
6
|
+
end
|
7
|
+
|
8
|
+
def !=(other_object)
|
9
|
+
!(self == other_object)
|
10
|
+
end
|
11
|
+
|
12
|
+
def ===(other_object)
|
13
|
+
other_object.kind_of?(self.class) && self == other_object
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
class MemoryModel::Base::Fieldable::Field
|
2
|
+
|
3
|
+
attr_reader :name, :options
|
4
|
+
delegate :inspect, to: :to_sym
|
5
|
+
|
6
|
+
def initialize(name, options={ })
|
7
|
+
@name = name.to_sym
|
8
|
+
@options = options.reverse_merge!({ readonly: false, comparable: true })
|
9
|
+
end
|
10
|
+
|
11
|
+
def ==(other_object)
|
12
|
+
self.to_sym == other_object.to_sym
|
13
|
+
end
|
14
|
+
|
15
|
+
def comparable?
|
16
|
+
!!@options[:comparable]
|
17
|
+
end
|
18
|
+
|
19
|
+
def default
|
20
|
+
@options[:default]
|
21
|
+
end
|
22
|
+
|
23
|
+
def readonly?
|
24
|
+
!!@options[:readonly]
|
25
|
+
end
|
26
|
+
|
27
|
+
def to_sym
|
28
|
+
@name.to_sym
|
29
|
+
end
|
30
|
+
|
31
|
+
def to_s
|
32
|
+
@name.to_s
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
require 'active_support/core_ext/hash/keys'
|
2
|
+
require 'set'
|
3
|
+
|
4
|
+
class MemoryModel::Base::Fieldable::FieldSet
|
5
|
+
|
6
|
+
Field = MemoryModel::Base::Fieldable::Field
|
7
|
+
|
8
|
+
attr_reader :fields
|
9
|
+
delegate :include?, to: :fields
|
10
|
+
|
11
|
+
def initialize
|
12
|
+
@fields = []
|
13
|
+
end
|
14
|
+
|
15
|
+
def [](name)
|
16
|
+
@fields.find { |f| f.name == name.to_sym }
|
17
|
+
end
|
18
|
+
|
19
|
+
def <<(attr)
|
20
|
+
attr = Field.new(attr) unless attr.is_a? Field
|
21
|
+
@fields << attr
|
22
|
+
end
|
23
|
+
|
24
|
+
def add(attr, options={ })
|
25
|
+
@fields.delete_if { |f| f == attr }
|
26
|
+
@fields << Field.new(attr, options)
|
27
|
+
end
|
28
|
+
|
29
|
+
def comparable
|
30
|
+
@fields.select(&:comparable?).map(&:to_sym)
|
31
|
+
end
|
32
|
+
|
33
|
+
def inspect
|
34
|
+
to_a.inspect
|
35
|
+
end
|
36
|
+
|
37
|
+
def default_values(model, attributes={ })
|
38
|
+
@fields.reduce(attributes.symbolize_keys) do |attrs, field|
|
39
|
+
raise MemoryModel::ReadonlyFieldError if attrs[field.name].present? && field.readonly?
|
40
|
+
default = field.default.is_a?(Symbol) ? field.default.to_proc : field.default
|
41
|
+
attrs[field.name] ||= if default.nil?
|
42
|
+
nil
|
43
|
+
elsif default.is_a? String
|
44
|
+
default
|
45
|
+
elsif default.not_a?(::Proc)
|
46
|
+
raise ArgumentError, "#{default} must be a string, symbol, lamba or proc"
|
47
|
+
elsif default.lambda? && default.arity == 0
|
48
|
+
default.call
|
49
|
+
elsif default.arity.in? -1..0
|
50
|
+
model.instance_eval(&default)
|
51
|
+
elsif default.arity == 1
|
52
|
+
default.yield model
|
53
|
+
else
|
54
|
+
raise ArgumentError, "#{default} must have an arity of 0..1, got #{default.arity}"
|
55
|
+
end
|
56
|
+
attrs
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def to_a
|
61
|
+
@fields.map(&:to_sym)
|
62
|
+
end
|
63
|
+
|
64
|
+
private
|
65
|
+
|
66
|
+
def method_missing(m, *args, &block)
|
67
|
+
if to_a.respond_to? m
|
68
|
+
to_a.send m, *args, &block
|
69
|
+
else
|
70
|
+
super
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'active_support/concern'
|
2
|
+
require 'active_support/dependencies/autoload'
|
3
|
+
require 'securerandom'
|
4
|
+
|
5
|
+
module MemoryModel::Base::Fieldable
|
6
|
+
extend ConcernedInheritance
|
7
|
+
extend ActiveSupport::Concern
|
8
|
+
extend ActiveSupport::Autoload
|
9
|
+
include ActiveModel::AttributeMethods
|
10
|
+
|
11
|
+
autoload :FieldSet
|
12
|
+
autoload :Field
|
13
|
+
|
14
|
+
inherited do
|
15
|
+
instance_variable_set :@fields, baseclass.fields
|
16
|
+
field :id, readonly: true, default: -> { SecureRandom.uuid }, comparable: false
|
17
|
+
end
|
18
|
+
|
19
|
+
module ClassMethods
|
20
|
+
def field(attr, options={ })
|
21
|
+
define_attribute_method attr unless instance_method_already_implemented? attr
|
22
|
+
fields.add(attr.to_sym, options)
|
23
|
+
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
24
|
+
def #{attr}
|
25
|
+
read_attribute :#{attr}
|
26
|
+
end
|
27
|
+
|
28
|
+
def #{attr}=(value)
|
29
|
+
write_attribute :#{attr}, value
|
30
|
+
end
|
31
|
+
RUBY
|
32
|
+
end
|
33
|
+
|
34
|
+
def fields
|
35
|
+
return nil if self == MemoryModel::Base
|
36
|
+
@fields ||= FieldSet.new
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
def fields
|
42
|
+
self.class.fields
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module MemoryModel::Base::Versionable
|
2
|
+
|
3
|
+
def versions
|
4
|
+
instances = self.class.collection.records.select { |i| i.id == self.id }
|
5
|
+
instances.reduce({ }) do |hash, instance|
|
6
|
+
hash[instance.version] = instance
|
7
|
+
hash
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def version
|
12
|
+
@version
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
|
17
|
+
# MemoryModel::Base::Immutable # todo!
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require "concerned_inheritance"
|
2
|
+
require 'active_support/core_ext/object'
|
3
|
+
require 'active_support/core_ext/hash'
|
4
|
+
require 'active_support/dependencies/autoload'
|
5
|
+
require 'active_support/core_ext/hash/indifferent_access'
|
6
|
+
require 'active_model'
|
7
|
+
|
8
|
+
class MemoryModel::Base
|
9
|
+
extend ActiveSupport::Autoload
|
10
|
+
extend ConcernedInheritance
|
11
|
+
|
12
|
+
autoload :Fieldable
|
13
|
+
autoload :Collectable
|
14
|
+
autoload :Comparable
|
15
|
+
autoload :Actionable
|
16
|
+
autoload :Attributable
|
17
|
+
autoload :Versionable
|
18
|
+
autoload :Persistence
|
19
|
+
|
20
|
+
# Active Model Additions
|
21
|
+
extend ActiveModel::Callbacks
|
22
|
+
extend ActiveModel::Naming
|
23
|
+
extend ActiveModel::Translation
|
24
|
+
include ActiveModel::Conversion
|
25
|
+
include ActiveModel::MassAssignmentSecurity
|
26
|
+
include ActiveModel::Observing
|
27
|
+
include ActiveModel::Serialization
|
28
|
+
include ActiveModel::Validations
|
29
|
+
|
30
|
+
# Memory Model Additions
|
31
|
+
include Fieldable
|
32
|
+
include Collectable
|
33
|
+
include Comparable
|
34
|
+
include Actionable
|
35
|
+
include Attributable
|
36
|
+
include Versionable
|
37
|
+
include Persistence
|
38
|
+
|
39
|
+
# Active Model Callbacks
|
40
|
+
define_model_callbacks :initialize, only: [:after]
|
41
|
+
|
42
|
+
def initialize(attributes={ })
|
43
|
+
unless self.class.collection.is_a? MemoryModel::Collection
|
44
|
+
raise MemoryModel::InvalidCollectionError, "#{self.class} does not have an assigned collection"
|
45
|
+
end
|
46
|
+
@attributes = fields.default_values(self, attributes).with_indifferent_access
|
47
|
+
@deleted = false
|
48
|
+
run_callbacks :initialize
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|