memory_model 0.0.2 → 0.1.0
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.
- checksums.yaml +15 -0
- data/.ruby-version +1 -0
- data/.travis.yml +7 -4
- data/Appraisals +9 -0
- data/Guardfile +7 -1
- data/README.md +5 -1
- data/Rakefile +12 -0
- data/gemfiles/rails_3.gemfile +8 -0
- data/gemfiles/rails_3.gemfile.lock +109 -0
- data/gemfiles/rails_4.gemfile +8 -0
- data/gemfiles/rails_4.gemfile.lock +117 -0
- data/lib/memory_model/base/actions/class_methods.rb +27 -0
- data/lib/memory_model/base/actions.rb +75 -0
- data/lib/memory_model/base/attributes.rb +87 -0
- data/lib/memory_model/base/auto_increment.rb +47 -0
- data/lib/memory_model/base/collectible.rb +26 -0
- data/lib/memory_model/base/conversion.rb +11 -0
- data/lib/memory_model/base/fields/field.rb +57 -0
- data/lib/memory_model/base/fields/field_set.rb +87 -0
- data/lib/memory_model/base/fields.rb +49 -0
- data/lib/memory_model/base/operations/comparisons.rb +25 -0
- data/lib/memory_model/base/operations.rb +10 -0
- data/lib/memory_model/base/persistence.rb +13 -11
- data/lib/memory_model/base.rb +58 -43
- data/lib/memory_model/collection/finders.rb +75 -0
- data/lib/memory_model/collection/index/multi.rb +61 -0
- data/lib/memory_model/collection/index/unique.rb +79 -0
- data/lib/memory_model/collection/index.rb +86 -0
- data/lib/memory_model/collection/initializers.rb +48 -0
- data/lib/memory_model/collection/loader_delegate.rb +63 -0
- data/lib/memory_model/collection/marshaled_record.rb +23 -0
- data/lib/memory_model/collection/operations.rb +82 -0
- data/lib/memory_model/collection.rb +18 -73
- data/lib/memory_model/version.rb +1 -1
- data/lib/memory_model.rb +7 -7
- data/memory_model.gemspec +8 -3
- data/spec/benchmark/benchmark.rb +126 -0
- data/spec/memory_model/base/{actionable_spec.rb → actions_spec.rb} +34 -103
- data/spec/memory_model/base/{attributable_spec.rb → attributes_spec.rb} +4 -6
- data/spec/memory_model/base/{collectable_spec.rb → collectible_spec.rb} +1 -1
- data/spec/memory_model/base/fieldable/field_set_spec.rb +23 -37
- data/spec/memory_model/base/fieldable/field_spec.rb +16 -16
- data/spec/memory_model/base/{fieldable_spec.rb → fields_spec.rb} +1 -1
- data/spec/memory_model/base/{comparable_spec.rb → operations/comparisons_spec.rb} +4 -4
- data/spec/memory_model/base/persistence_spec.rb +2 -2
- data/spec/memory_model/base_spec.rb +10 -9
- data/spec/memory_model/collection_spec.rb +24 -146
- data/spec/spec_helper.rb +11 -0
- data/spec/support/delegate_matcher.rb +40 -0
- metadata +120 -65
- data/.idea/.rakeTasks +0 -7
- data/.idea/dictionaries/jwaldrip.xml +0 -3
- data/.idea/encodings.xml +0 -5
- data/.idea/memory_model.iml +0 -47
- data/.idea/misc.xml +0 -8
- data/.idea/modules.xml +0 -9
- data/.idea/scopes/scope_settings.xml +0 -5
- data/.idea/vcs.xml +0 -7
- data/.idea/workspace.xml +0 -701
- data/lib/memory_model/base/actionable.rb +0 -95
- data/lib/memory_model/base/attributable.rb +0 -76
- data/lib/memory_model/base/collectable.rb +0 -22
- data/lib/memory_model/base/comparable.rb +0 -16
- data/lib/memory_model/base/fieldable/field.rb +0 -35
- data/lib/memory_model/base/fieldable/field_set.rb +0 -74
- data/lib/memory_model/base/fieldable.rb +0 -45
- data/lib/memory_model/base/versionable.rb +0 -17
- data/lib/memory_model/core_ext/object.rb +0 -5
- data/spec/memory_model/base/versionable_spec.rb +0 -31
- data/spec/memory_model/core_ext/object_spec.rb +0 -12
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
MjIyNWNmNzg5ZDI5ZWU3OGNkY2MyZTg3MWE3Y2FmM2JkYmNlNzkzNQ==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
MDhkNDU2YjhiMzI1MjNhZmZkMTJmMzQxNWIzNDc0MDdjYzVmOTZhYg==
|
7
|
+
SHA512:
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
ODcwZDk4NTdkZjYyNjRjY2Y0NWY4YTQ0OTMwZjI4NDdjZmRmYTg2NGNkOTVl
|
10
|
+
NWIyNzllMWI3ZGI1ZDZjN2IxNDUwMmM1ZmZiMjYzZTI4NDM1MTlmY2VjYWQ0
|
11
|
+
YTBiZjgwNjNhOTBjOTZmZjRkZmQzZDU5ZTAwYzM5YmIwNDM4MzA=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
N2U4Y2JiOWYwMDY2NzM3NDgzNWE0NmY2MzdhYjdkNmUxOTQzYTQxMjYxZjZh
|
14
|
+
NDlmODNhNTZiZDM5NzY3MWQwZDE3OWYwNTdhNjM3NGEzYjc5NDI3MjAxMjNh
|
15
|
+
Y2VkN2I2YjFlZTZmOTdhOWU0MGFlYzAzZDIxNjNmMGQ5NjY2MTI=
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
1.9.3-p448
|
data/.travis.yml
CHANGED
@@ -1,6 +1,9 @@
|
|
1
1
|
language: ruby
|
2
2
|
rvm:
|
3
|
-
-
|
4
|
-
-
|
5
|
-
|
6
|
-
|
3
|
+
- 2.1.0-preview1
|
4
|
+
- 2.0.0
|
5
|
+
- 1.9.3
|
6
|
+
|
7
|
+
gemfile:
|
8
|
+
- gemfiles/rails_3.gemfile
|
9
|
+
- gemfiles/rails_4.gemfile
|
data/Appraisals
ADDED
data/Guardfile
CHANGED
@@ -1,4 +1,10 @@
|
|
1
|
-
guard '
|
1
|
+
guard 'bundler' do
|
2
|
+
watch('Gemfile')
|
3
|
+
# Uncomment next line if Gemfile contain `gemspec' command
|
4
|
+
# watch(/^.+\.gemspec/)
|
5
|
+
end
|
6
|
+
|
7
|
+
guard 'rspec', after_all_pass: true, all_on_start: false do
|
2
8
|
watch(%r{^spec/.+_spec\.rb$})
|
3
9
|
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
|
4
10
|
watch('spec/spec_helper.rb') { "spec" }
|
data/README.md
CHANGED
@@ -1,4 +1,8 @@
|
|
1
|
-
[](http://allthebadges.io/jwaldrip/memory_model/badge_fury)
|
2
|
+
[](http://allthebadges.io/jwaldrip/memory_model/gemnasium)
|
3
|
+
[](http://allthebadges.io/jwaldrip/memory_model/travis)
|
4
|
+
[](http://allthebadges.io/jwaldrip/memory_model/coveralls)
|
5
|
+
[](http://allthebadges.io/jwaldrip/memory_model/code_climate)
|
2
6
|
|
3
7
|
# MemoryModel
|
4
8
|
|
data/Rakefile
CHANGED
@@ -1 +1,13 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
require "bundler/setup"
|
1
3
|
require "bundler/gem_tasks"
|
4
|
+
require 'appraisal'
|
5
|
+
require 'rspec/core/rake_task'
|
6
|
+
|
7
|
+
RSpec::Core::RakeTask.new(:spec)
|
8
|
+
|
9
|
+
task :benchmark do
|
10
|
+
require './spec/benchmark/benchmark'
|
11
|
+
end
|
12
|
+
|
13
|
+
task :default => [:spec, :benchmark]
|
@@ -0,0 +1,109 @@
|
|
1
|
+
PATH
|
2
|
+
remote: ../
|
3
|
+
specs:
|
4
|
+
memory_model (0.0.2)
|
5
|
+
activemodel (>= 3.2)
|
6
|
+
activesupport (>= 3.2)
|
7
|
+
concerned_inheritance
|
8
|
+
|
9
|
+
GEM
|
10
|
+
remote: https://rubygems.org/
|
11
|
+
specs:
|
12
|
+
activemodel (3.2.14)
|
13
|
+
activesupport (= 3.2.14)
|
14
|
+
builder (~> 3.0.0)
|
15
|
+
activesupport (3.2.14)
|
16
|
+
i18n (~> 0.6, >= 0.6.4)
|
17
|
+
multi_json (~> 1.0)
|
18
|
+
appraisal (0.5.2)
|
19
|
+
bundler
|
20
|
+
rake
|
21
|
+
builder (3.0.4)
|
22
|
+
celluloid (0.15.2)
|
23
|
+
timers (~> 1.1.0)
|
24
|
+
coderay (1.0.9)
|
25
|
+
colorize (0.5.8)
|
26
|
+
concerned_inheritance (0.0.2)
|
27
|
+
activesupport
|
28
|
+
coveralls (0.7.0)
|
29
|
+
multi_json (~> 1.3)
|
30
|
+
rest-client
|
31
|
+
simplecov (>= 0.7)
|
32
|
+
term-ansicolor
|
33
|
+
thor
|
34
|
+
diff-lcs (1.2.4)
|
35
|
+
faker (1.2.0)
|
36
|
+
i18n (~> 0.5)
|
37
|
+
ffi (1.9.0)
|
38
|
+
formatador (0.2.4)
|
39
|
+
guard (2.0.5)
|
40
|
+
formatador (>= 0.2.4)
|
41
|
+
listen (~> 2.0)
|
42
|
+
lumberjack (~> 1.0)
|
43
|
+
pry (>= 0.9.12)
|
44
|
+
thor (>= 0.18.1)
|
45
|
+
guard-bundler (0.1.3)
|
46
|
+
bundler (>= 1.0.0)
|
47
|
+
guard (>= 0.2.2)
|
48
|
+
guard-rspec (4.0.1)
|
49
|
+
guard (~> 2.0)
|
50
|
+
rspec (~> 2.14)
|
51
|
+
i18n (0.6.5)
|
52
|
+
listen (2.1.0)
|
53
|
+
celluloid (>= 0.15.2)
|
54
|
+
rb-fsevent (>= 0.9.3)
|
55
|
+
rb-inotify (>= 0.9)
|
56
|
+
lumberjack (1.0.4)
|
57
|
+
method_source (0.8.2)
|
58
|
+
mime-types (1.25)
|
59
|
+
multi_json (1.8.1)
|
60
|
+
pry (0.9.12.2)
|
61
|
+
coderay (~> 1.0.5)
|
62
|
+
method_source (~> 0.8)
|
63
|
+
slop (~> 3.4)
|
64
|
+
rake (10.1.0)
|
65
|
+
rb-fsevent (0.9.3)
|
66
|
+
rb-inotify (0.9.2)
|
67
|
+
ffi (>= 0.5.0)
|
68
|
+
rest-client (1.6.7)
|
69
|
+
mime-types (>= 1.16)
|
70
|
+
rspec (2.14.1)
|
71
|
+
rspec-core (~> 2.14.0)
|
72
|
+
rspec-expectations (~> 2.14.0)
|
73
|
+
rspec-mocks (~> 2.14.0)
|
74
|
+
rspec-core (2.14.5)
|
75
|
+
rspec-expectations (2.14.3)
|
76
|
+
diff-lcs (>= 1.1.3, < 2.0)
|
77
|
+
rspec-mocks (2.14.3)
|
78
|
+
simplecov (0.7.1)
|
79
|
+
multi_json (~> 1.0)
|
80
|
+
simplecov-html (~> 0.7.1)
|
81
|
+
simplecov-html (0.7.1)
|
82
|
+
slop (3.4.6)
|
83
|
+
term-ansicolor (1.2.2)
|
84
|
+
tins (~> 0.8)
|
85
|
+
terminal-notifier-guard (1.5.3)
|
86
|
+
test-unit (2.5.5)
|
87
|
+
thor (0.18.1)
|
88
|
+
timers (1.1.0)
|
89
|
+
tins (0.12.0)
|
90
|
+
|
91
|
+
PLATFORMS
|
92
|
+
ruby
|
93
|
+
|
94
|
+
DEPENDENCIES
|
95
|
+
activemodel (= 3.2.14)
|
96
|
+
activesupport (= 3.2.14)
|
97
|
+
appraisal
|
98
|
+
colorize
|
99
|
+
coveralls
|
100
|
+
faker
|
101
|
+
guard-bundler
|
102
|
+
guard-rspec
|
103
|
+
memory_model!
|
104
|
+
pry
|
105
|
+
rb-fsevent
|
106
|
+
rspec
|
107
|
+
simplecov
|
108
|
+
terminal-notifier-guard
|
109
|
+
test-unit
|
@@ -0,0 +1,117 @@
|
|
1
|
+
PATH
|
2
|
+
remote: ../
|
3
|
+
specs:
|
4
|
+
memory_model (0.0.2)
|
5
|
+
activemodel (>= 3.2)
|
6
|
+
activesupport (>= 3.2)
|
7
|
+
concerned_inheritance
|
8
|
+
|
9
|
+
GEM
|
10
|
+
remote: https://rubygems.org/
|
11
|
+
specs:
|
12
|
+
activemodel (4.0.0)
|
13
|
+
activesupport (= 4.0.0)
|
14
|
+
builder (~> 3.1.0)
|
15
|
+
activesupport (4.0.0)
|
16
|
+
i18n (~> 0.6, >= 0.6.4)
|
17
|
+
minitest (~> 4.2)
|
18
|
+
multi_json (~> 1.3)
|
19
|
+
thread_safe (~> 0.1)
|
20
|
+
tzinfo (~> 0.3.37)
|
21
|
+
appraisal (0.5.2)
|
22
|
+
bundler
|
23
|
+
rake
|
24
|
+
atomic (1.1.14)
|
25
|
+
builder (3.1.4)
|
26
|
+
celluloid (0.15.2)
|
27
|
+
timers (~> 1.1.0)
|
28
|
+
coderay (1.0.9)
|
29
|
+
colorize (0.5.8)
|
30
|
+
concerned_inheritance (0.0.2)
|
31
|
+
activesupport
|
32
|
+
coveralls (0.7.0)
|
33
|
+
multi_json (~> 1.3)
|
34
|
+
rest-client
|
35
|
+
simplecov (>= 0.7)
|
36
|
+
term-ansicolor
|
37
|
+
thor
|
38
|
+
diff-lcs (1.2.4)
|
39
|
+
faker (1.2.0)
|
40
|
+
i18n (~> 0.5)
|
41
|
+
ffi (1.9.0)
|
42
|
+
formatador (0.2.4)
|
43
|
+
guard (2.0.5)
|
44
|
+
formatador (>= 0.2.4)
|
45
|
+
listen (~> 2.0)
|
46
|
+
lumberjack (~> 1.0)
|
47
|
+
pry (>= 0.9.12)
|
48
|
+
thor (>= 0.18.1)
|
49
|
+
guard-bundler (0.1.3)
|
50
|
+
bundler (>= 1.0.0)
|
51
|
+
guard (>= 0.2.2)
|
52
|
+
guard-rspec (4.0.1)
|
53
|
+
guard (~> 2.0)
|
54
|
+
rspec (~> 2.14)
|
55
|
+
i18n (0.6.5)
|
56
|
+
listen (2.1.0)
|
57
|
+
celluloid (>= 0.15.2)
|
58
|
+
rb-fsevent (>= 0.9.3)
|
59
|
+
rb-inotify (>= 0.9)
|
60
|
+
lumberjack (1.0.4)
|
61
|
+
method_source (0.8.2)
|
62
|
+
mime-types (1.25)
|
63
|
+
minitest (4.7.5)
|
64
|
+
multi_json (1.8.1)
|
65
|
+
pry (0.9.12.2)
|
66
|
+
coderay (~> 1.0.5)
|
67
|
+
method_source (~> 0.8)
|
68
|
+
slop (~> 3.4)
|
69
|
+
rake (10.1.0)
|
70
|
+
rb-fsevent (0.9.3)
|
71
|
+
rb-inotify (0.9.2)
|
72
|
+
ffi (>= 0.5.0)
|
73
|
+
rest-client (1.6.7)
|
74
|
+
mime-types (>= 1.16)
|
75
|
+
rspec (2.14.1)
|
76
|
+
rspec-core (~> 2.14.0)
|
77
|
+
rspec-expectations (~> 2.14.0)
|
78
|
+
rspec-mocks (~> 2.14.0)
|
79
|
+
rspec-core (2.14.5)
|
80
|
+
rspec-expectations (2.14.3)
|
81
|
+
diff-lcs (>= 1.1.3, < 2.0)
|
82
|
+
rspec-mocks (2.14.3)
|
83
|
+
simplecov (0.7.1)
|
84
|
+
multi_json (~> 1.0)
|
85
|
+
simplecov-html (~> 0.7.1)
|
86
|
+
simplecov-html (0.7.1)
|
87
|
+
slop (3.4.6)
|
88
|
+
term-ansicolor (1.2.2)
|
89
|
+
tins (~> 0.8)
|
90
|
+
terminal-notifier-guard (1.5.3)
|
91
|
+
test-unit (2.5.5)
|
92
|
+
thor (0.18.1)
|
93
|
+
thread_safe (0.1.3)
|
94
|
+
atomic
|
95
|
+
timers (1.1.0)
|
96
|
+
tins (0.12.0)
|
97
|
+
tzinfo (0.3.38)
|
98
|
+
|
99
|
+
PLATFORMS
|
100
|
+
ruby
|
101
|
+
|
102
|
+
DEPENDENCIES
|
103
|
+
activemodel (= 4.0.0)
|
104
|
+
activesupport (= 4.0.0)
|
105
|
+
appraisal
|
106
|
+
colorize
|
107
|
+
coveralls
|
108
|
+
faker
|
109
|
+
guard-bundler
|
110
|
+
guard-rspec
|
111
|
+
memory_model!
|
112
|
+
pry
|
113
|
+
rb-fsevent
|
114
|
+
rspec
|
115
|
+
simplecov
|
116
|
+
terminal-notifier-guard
|
117
|
+
test-unit
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module MemoryModel
|
2
|
+
class Base
|
3
|
+
module Actions
|
4
|
+
module ClassMethods
|
5
|
+
|
6
|
+
def create(attributes={})
|
7
|
+
new(attributes).tap(&:save)
|
8
|
+
end
|
9
|
+
|
10
|
+
def create!(attributes={})
|
11
|
+
new(attributes).tap(&:save!)
|
12
|
+
end
|
13
|
+
|
14
|
+
def delete_all
|
15
|
+
count.tap do
|
16
|
+
self.collection.clear
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def destroy_all
|
21
|
+
self.all.each(&:destroy)
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
module MemoryModel
|
2
|
+
|
3
|
+
class RecordInvalid < MemoryModel::Error
|
4
|
+
attr_reader :record # :nodoc:
|
5
|
+
def initialize(record) # :nodoc:
|
6
|
+
@record = record
|
7
|
+
errors = @record.errors.full_messages.join(", ")
|
8
|
+
super(errors)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
class Base
|
13
|
+
module Actions
|
14
|
+
extend ActiveSupport::Concern
|
15
|
+
extend ActiveSupport::Autoload
|
16
|
+
|
17
|
+
autoload :ClassMethods
|
18
|
+
|
19
|
+
included do
|
20
|
+
define_model_callbacks :create, :update, :save, :destroy, :validation
|
21
|
+
define_model_callbacks :commit, only: :after
|
22
|
+
before_save(:remove_invalid_instance_vars)
|
23
|
+
end
|
24
|
+
|
25
|
+
VALID_IVARS = [
|
26
|
+
:@attributes
|
27
|
+
]
|
28
|
+
|
29
|
+
def delete
|
30
|
+
self.class.collection.delete(self)
|
31
|
+
freeze
|
32
|
+
end
|
33
|
+
|
34
|
+
def destroy
|
35
|
+
run_callbacks :destroy do
|
36
|
+
delete
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def save(options={})
|
41
|
+
!!perform_validations(options) ? commit : false
|
42
|
+
end
|
43
|
+
|
44
|
+
def save!(options={})
|
45
|
+
!!perform_validations(options) ? commit : raise(RecordInvalid.new(self))
|
46
|
+
end
|
47
|
+
|
48
|
+
private
|
49
|
+
|
50
|
+
def commit
|
51
|
+
operation = persisted? ? :update : :create
|
52
|
+
run_callbacks operation do
|
53
|
+
run_callbacks :save do
|
54
|
+
self.class.collection.send(operation, self)
|
55
|
+
run_callbacks :commit
|
56
|
+
end
|
57
|
+
end
|
58
|
+
self
|
59
|
+
end
|
60
|
+
|
61
|
+
def remove_invalid_instance_vars
|
62
|
+
instance_variables.reject { |ivar| ivar.in? VALID_IVARS }.each do |ivar|
|
63
|
+
remove_instance_variable ivar if instance_variable_defined?(ivar)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def perform_validations(options={})
|
68
|
+
run_callbacks :validation do
|
69
|
+
options[:validate] == false || valid?(options[:context])
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
require 'active_support/core_ext/module/delegation'
|
2
|
+
require 'active_support/core_ext/hash/indifferent_access'
|
3
|
+
require 'active_support/hash_with_indifferent_access'
|
4
|
+
|
5
|
+
module MemoryModel
|
6
|
+
class Base
|
7
|
+
module Attributes
|
8
|
+
extend ActiveSupport::Concern
|
9
|
+
include ActiveModel::AttributeMethods
|
10
|
+
include ActiveModel::Dirty
|
11
|
+
|
12
|
+
included do
|
13
|
+
delegate :to_hash, to: :attributes
|
14
|
+
attribute_method_affix :prefix => 'reset_', :suffix => '_to_default!'
|
15
|
+
attribute_method_prefix 'clear_'
|
16
|
+
end
|
17
|
+
|
18
|
+
def attributes
|
19
|
+
@attributes ||= HashWithIndifferentAccess.new
|
20
|
+
end
|
21
|
+
|
22
|
+
def attributes=(hash)
|
23
|
+
hash.reduce({}) do |hash, (attr, value)|
|
24
|
+
hash.merge attr => write_attribute(attr, value)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def has_attribute?(key)
|
29
|
+
case value = @attributes[key]
|
30
|
+
when NilClass, String
|
31
|
+
!value.nil?
|
32
|
+
else
|
33
|
+
value.present?
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def inspect
|
38
|
+
inspection = fields.reduce([]) { |array, field|
|
39
|
+
name = field.name
|
40
|
+
array << "#{name}: #{attribute_for_inspect(name)}" if has_attribute?(name)
|
41
|
+
array
|
42
|
+
}.join(", ")
|
43
|
+
inspection = ' ' + inspection if inspection.present?
|
44
|
+
super.sub /^(#<[a-z:0-9]+).*>/i, "\\1#{inspection}>"
|
45
|
+
end
|
46
|
+
|
47
|
+
def read_attribute(name)
|
48
|
+
attributes[name]
|
49
|
+
end
|
50
|
+
|
51
|
+
alias :[] :read_attribute
|
52
|
+
|
53
|
+
def write_attribute(name, value)
|
54
|
+
raise InvalidFieldError, name unless fields.include? name
|
55
|
+
raise ReadOnlyFieldError, name if fields[name].options[:readonly] && persisted?
|
56
|
+
|
57
|
+
send "#{name}_will_change!" unless value == read_attribute(name) || new_record?
|
58
|
+
attributes[name] = value
|
59
|
+
end
|
60
|
+
|
61
|
+
alias :[]= :write_attribute
|
62
|
+
|
63
|
+
protected
|
64
|
+
|
65
|
+
def attribute_for_inspect(attr_name)
|
66
|
+
value = read_attribute(attr_name)
|
67
|
+
|
68
|
+
if value.is_a?(String) && value.length > 50
|
69
|
+
"#{value[0..50]}...".inspect
|
70
|
+
elsif value.is_a?(Date) || value.is_a?(Time)
|
71
|
+
value.to_s
|
72
|
+
else
|
73
|
+
value.inspect
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def clear_attribute(attr)
|
78
|
+
write_attribute attr, nil
|
79
|
+
end
|
80
|
+
|
81
|
+
def reset_attribute_to_default!(attr)
|
82
|
+
fields.set_default_value(self, attr)
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module MemoryModel
|
2
|
+
class Base
|
3
|
+
module AutoIncrement
|
4
|
+
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
included do
|
8
|
+
before_create(:auto_increment_fields!)
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def auto_increment_fields!
|
14
|
+
fields.select { |field| field.options[:auto_increment] === true }.each do |field|
|
15
|
+
write_attribute(field.name, self.class.auto_increment_for!(field.name))
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def reset_incremented_fields!
|
20
|
+
fields.select { |field| field.options[:auto_increment] === true }.each do |field|
|
21
|
+
clear_attribute(field.name)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
module ClassMethods
|
26
|
+
|
27
|
+
def auto_increment_for!(field)
|
28
|
+
fields[field].increment!
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
module Fields
|
36
|
+
class Field
|
37
|
+
|
38
|
+
def increment!
|
39
|
+
raise ArguementError, "#{name} is not incrementable" unless options[:auto_increment] === true
|
40
|
+
@incrementor ||= 0
|
41
|
+
@incrementor += 1
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'active_support/concern'
|
2
|
+
require 'active_support/core_ext/module/delegation'
|
3
|
+
|
4
|
+
module MemoryModel
|
5
|
+
class Base
|
6
|
+
module Collectible
|
7
|
+
extend ActiveSupport::Concern
|
8
|
+
extend ConcernedInheritance
|
9
|
+
|
10
|
+
inherited do
|
11
|
+
instance_variable_set :@collection, baseclass.collection
|
12
|
+
end
|
13
|
+
|
14
|
+
module ClassMethods
|
15
|
+
delegate *(MemoryModel::Collection.instance_methods - Object.instance_methods), to: :collection
|
16
|
+
delegate :first, :last, to: :all
|
17
|
+
|
18
|
+
def collection
|
19
|
+
return nil if self == MemoryModel::Base
|
20
|
+
@collection ||= MemoryModel::Collection.new(self)
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module MemoryModel
|
2
|
+
|
3
|
+
class InvalidFieldError < Error
|
4
|
+
|
5
|
+
def initialize(name)
|
6
|
+
super("`#{name}` is not a valid field")
|
7
|
+
end
|
8
|
+
|
9
|
+
end
|
10
|
+
|
11
|
+
class ReadOnlyFieldError < Error
|
12
|
+
|
13
|
+
def initialize(name)
|
14
|
+
super("`#{name}` is read only")
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
class Base
|
20
|
+
module Fields
|
21
|
+
class Field
|
22
|
+
|
23
|
+
attr_reader :name, :options
|
24
|
+
|
25
|
+
def initialize(name, options={})
|
26
|
+
@name = name.to_sym
|
27
|
+
@options = options.reverse_merge!({ readonly: false, comparable: true })
|
28
|
+
end
|
29
|
+
|
30
|
+
def ==(other_object)
|
31
|
+
self.to_sym == other_object.to_sym
|
32
|
+
end
|
33
|
+
|
34
|
+
def comparable?
|
35
|
+
!!@options[:comparable]
|
36
|
+
end
|
37
|
+
|
38
|
+
def default
|
39
|
+
@options[:default]
|
40
|
+
end
|
41
|
+
|
42
|
+
def readonly?
|
43
|
+
!!@options[:readonly]
|
44
|
+
end
|
45
|
+
|
46
|
+
def to_sym
|
47
|
+
@name.to_sym
|
48
|
+
end
|
49
|
+
|
50
|
+
def to_s
|
51
|
+
@name.to_s
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|