memory_model 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
+
[](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
|