ar_doc_store 1.0.5 → 2.0.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 +4 -4
- data/ar_doc_store.gemspec +3 -3
- data/lib/ar_doc_store.rb +30 -28
- data/lib/ar_doc_store/attributes/array.rb +25 -0
- data/lib/ar_doc_store/attributes/base.rb +72 -0
- data/lib/ar_doc_store/attributes/boolean.rb +17 -0
- data/lib/ar_doc_store/attributes/callback_support.rb +21 -0
- data/lib/ar_doc_store/attributes/date.rb +21 -0
- data/lib/ar_doc_store/attributes/datetime.rb +21 -0
- data/lib/ar_doc_store/attributes/decimal.rb +17 -0
- data/lib/ar_doc_store/attributes/embeds_base.rb +35 -0
- data/lib/ar_doc_store/attributes/embeds_many.rb +143 -0
- data/lib/ar_doc_store/{attribute_types/embeds_one_attribute.rb → attributes/embeds_one.rb} +25 -30
- data/lib/ar_doc_store/{attribute_types/enumeration_attribute.rb → attributes/enumeration.rb} +2 -6
- data/lib/ar_doc_store/{attribute_types/float_attribute.rb → attributes/float.rb} +5 -8
- data/lib/ar_doc_store/{attribute_types/integer_attribute.rb → attributes/integer.rb} +5 -8
- data/lib/ar_doc_store/attributes/string.rb +13 -0
- data/lib/ar_doc_store/embeddable_model.rb +51 -75
- data/lib/ar_doc_store/embedded_collection.rb +14 -0
- data/lib/ar_doc_store/embedding.rb +0 -2
- data/lib/ar_doc_store/model.rb +18 -8
- data/lib/ar_doc_store/storage.rb +4 -127
- data/lib/ar_doc_store/types/embeds_many.rb +52 -0
- data/lib/ar_doc_store/types/embeds_one.rb +42 -0
- data/lib/ar_doc_store/version.rb +1 -1
- data/test/{attribute_types → attributes}/array_attribute_test.rb +5 -1
- data/test/{attribute_types → attributes}/boolean_attribute_test.rb +7 -1
- data/test/attributes/date_attribute_test.rb +52 -0
- data/test/attributes/datetime_attribute_test.rb +54 -0
- data/test/attributes/decimal_attribute_test.rb +38 -0
- data/test/attributes/embeds_many_attribute_test.rb +78 -0
- data/test/attributes/embeds_one_attribute_test.rb +80 -0
- data/test/{attribute_types → attributes}/enumeration_attribute_test.rb +5 -0
- data/test/{attribute_types → attributes}/float_attribute_test.rb +6 -1
- data/test/attributes/integer_attribute_test.rb +63 -0
- data/test/{attribute_types → attributes}/string_attribute_test.rb +6 -0
- data/test/test_helper.rb +22 -94
- metadata +57 -35
- data/lib/ar_doc_store/attribute_types/array_attribute.rb +0 -30
- data/lib/ar_doc_store/attribute_types/base_attribute.rb +0 -61
- data/lib/ar_doc_store/attribute_types/boolean_attribute.rb +0 -25
- data/lib/ar_doc_store/attribute_types/datetime_attribute.rb +0 -17
- data/lib/ar_doc_store/attribute_types/embeds_many_attribute.rb +0 -165
- data/lib/ar_doc_store/attribute_types/string_attribute.rb +0 -17
- data/lib/ar_doc_store/attribute_types/uuid_attribute.rb +0 -30
- data/test/attribute_types/datetime_attribute_test.rb +0 -35
- data/test/attribute_types/integer_attribute_test.rb +0 -33
- data/test/originals/dirty_attributes_test.rb +0 -35
- data/test/originals/embedded_model_attribute_test.rb +0 -23
- data/test/originals/embedding_test.rb +0 -82
@@ -0,0 +1,63 @@
|
|
1
|
+
require_relative './../test_helper'
|
2
|
+
|
3
|
+
class IntegerAttributeTest < MiniTest::Test
|
4
|
+
|
5
|
+
def test_string_attribute_on_model_init
|
6
|
+
b = Building.new stories: 5
|
7
|
+
assert_equal 5, b.stories
|
8
|
+
end
|
9
|
+
|
10
|
+
def test_string_attribute_on_existing_model
|
11
|
+
b = Building.new
|
12
|
+
b.stories = 5
|
13
|
+
assert_equal 5, b.stories
|
14
|
+
assert b.stories_changed?
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_question_mark_method
|
18
|
+
b = Building.new stories: 5
|
19
|
+
assert_equal true, b.stories?
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_type_conversion_on_init
|
23
|
+
b = Building.new stories: '5'
|
24
|
+
assert_equal 5, b.stories
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_type_conversion_on_existing
|
28
|
+
b = Building.new
|
29
|
+
b.stories = '5'
|
30
|
+
assert_equal 5, b.stories
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_numeric_validation
|
34
|
+
b = Building.new
|
35
|
+
b.stories = 5
|
36
|
+
assert b.valid?
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_persistence
|
40
|
+
b = Building.new name: 'Test', stories: 5
|
41
|
+
assert b.save
|
42
|
+
assert_equal 5, Building.find(b.id).stories
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_default_value
|
46
|
+
b = Building.new
|
47
|
+
assert_equal 12, b.number_with_default
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_dirty_on_init
|
51
|
+
b = Building.new name: 'Foo'
|
52
|
+
assert b.name_changed?
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_dirty_persisted
|
56
|
+
a = Building.create name: 'Foo'
|
57
|
+
b = Building.find a.id
|
58
|
+
assert !b.name_changed?
|
59
|
+
b.name = 'Bar'
|
60
|
+
assert b.name_changed?
|
61
|
+
assert_equal 'Foo', b.name_was
|
62
|
+
end
|
63
|
+
end
|
data/test/test_helper.rb
CHANGED
@@ -7,82 +7,20 @@ require 'active_record'
|
|
7
7
|
require_relative './../lib/ar_doc_store'
|
8
8
|
ActiveRecord::Base.establish_connection(adapter: 'postgresql', database: 'ar_doc_store_test', username: 'postgres', password: 'postgres')
|
9
9
|
|
10
|
-
|
11
|
-
# An entrance has a door, a route, and some fields of its own
|
12
|
-
# A restroom has a door, a route, and some fields measuring the stalls
|
13
|
-
# Route and door
|
14
|
-
|
15
|
-
# This here is just to mock out enough AR behavior for a model to pretend to be an AR model without a database...
|
16
|
-
class ARDuck
|
17
|
-
include ActiveModel::AttributeMethods
|
18
|
-
include ActiveModel::Validations
|
19
|
-
include ActiveModel::Conversion
|
20
|
-
extend ActiveModel::Naming
|
21
|
-
include ActiveModel::Dirty
|
22
|
-
include ActiveModel::Serialization
|
23
|
-
|
24
|
-
attr_accessor :attributes
|
25
|
-
|
26
|
-
def initialize(attrs=nil)
|
27
|
-
@attributes = HashWithIndifferentAccess.new
|
28
|
-
unless attrs.nil?
|
29
|
-
attrs.each { |key, value|
|
30
|
-
@jattributes[key] = public_send("#{key}=", value)
|
31
|
-
}
|
32
|
-
end
|
33
|
-
@_initialized = true
|
34
|
-
end
|
35
|
-
|
36
|
-
def persisted?
|
37
|
-
false
|
38
|
-
end
|
39
|
-
|
40
|
-
def inspect
|
41
|
-
"#{self.class}: #{attributes.inspect}"
|
42
|
-
end
|
43
|
-
|
44
|
-
delegate :as_json, to: :attributes
|
45
|
-
|
46
|
-
def self.store_accessor(store, key)
|
47
|
-
key = key.to_sym
|
48
|
-
define_method key, -> { read_store_attribute(json_column, key) }
|
49
|
-
define_method "#{key}=".to_sym, -> (value) { write_store_attribute json_column, key, value }
|
50
|
-
end
|
51
|
-
|
52
|
-
def read_store_attribute(store, key)
|
53
|
-
@attributes[key]
|
54
|
-
end
|
55
|
-
|
56
|
-
def write_store_attribute(store, key, value)
|
57
|
-
#changed_json_attributes[key] = read_store_json_attribute(:data, key) if @_initialized
|
58
|
-
@attributes[key] = value
|
59
|
-
end
|
10
|
+
require 'active_record/migration'
|
60
11
|
|
12
|
+
ActiveRecord::Migration.execute "DROP TABLE IF EXISTS purchase_orders"
|
13
|
+
ActiveRecord::Migration.execute "DROP TABLE IF EXISTS buildings"
|
14
|
+
ActiveRecord::Migration.create_table :buildings do |t|
|
15
|
+
t.jsonb :data
|
61
16
|
end
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
end
|
66
|
-
|
67
|
-
class ThingWithEmptyModel < ARDuck
|
68
|
-
include ArDocStore::Model
|
69
|
-
embeds_one :empty_model
|
17
|
+
ActiveRecord::Migration.create_table :purchase_orders do |t|
|
18
|
+
t.jsonb :data
|
19
|
+
t.belongs_to :building, index: true, foreign_key: true
|
70
20
|
end
|
71
21
|
|
72
|
-
|
73
|
-
|
74
|
-
json_attribute :name
|
75
|
-
end
|
76
|
-
|
77
|
-
class EmbeddableB < EmbeddableA
|
78
|
-
json_attribute :gender
|
79
|
-
end
|
80
|
-
|
81
|
-
class Dimensions
|
82
|
-
include ArDocStore::EmbeddableModel
|
83
|
-
json_attribute :length, :float
|
84
|
-
json_attribute :width, :float
|
85
|
-
end
|
22
|
+
# require 'simplecov'
|
23
|
+
# SimpleCov.start
|
86
24
|
|
87
25
|
class Route
|
88
26
|
include ArDocStore::EmbeddableModel
|
@@ -101,29 +39,18 @@ class Door
|
|
101
39
|
json_attribute :clear_distance, as: :integer
|
102
40
|
json_attribute :opening_force, as: :integer
|
103
41
|
json_attribute :clear_space, as: :integer
|
42
|
+
|
43
|
+
validates :clear_space, numericality: { allow_nil: true }
|
104
44
|
end
|
105
45
|
|
106
46
|
class Entrance
|
107
47
|
include ArDocStore::EmbeddableModel
|
108
|
-
|
109
|
-
embeds_one :door
|
48
|
+
json_attribute :name
|
110
49
|
end
|
111
50
|
|
112
51
|
class Restroom
|
113
52
|
include ArDocStore::EmbeddableModel
|
114
|
-
|
115
|
-
embeds_one :door
|
116
|
-
|
117
|
-
enumerates :restroom_type, values: %w{single double dirty nasty clean}
|
118
|
-
|
119
|
-
json_attribute :is_restroom_provided, as: :boolean
|
120
|
-
json_attribute :is_signage_clear, as: :boolean
|
121
|
-
|
122
|
-
embeds_one :stall_area_dimensions, class_name: 'Dimensions'
|
123
|
-
embeds_one :sink_area_dimensions, class_name: 'Dimensions'
|
124
|
-
|
125
|
-
validates :restroom_type, presence: true
|
126
|
-
|
53
|
+
json_attribute :name
|
127
54
|
end
|
128
55
|
|
129
56
|
class Building < ActiveRecord::Base
|
@@ -132,19 +59,20 @@ class Building < ActiveRecord::Base
|
|
132
59
|
json_attribute :comments, as: :string
|
133
60
|
json_attribute :finished, :boolean
|
134
61
|
json_attribute :stories, as: :integer
|
62
|
+
json_attribute :number_with_default, as: :integer, default: 12
|
135
63
|
json_attribute :height, as: :float
|
136
64
|
json_attribute :architects, as: :array
|
137
65
|
json_attribute :construction, as: :enumeration, values: %w{concrete wood brick plaster steel}
|
138
66
|
json_attribute :multiconstruction, as: :enumeration, values: %w{concrete wood brick plaster steel}, multiple: true
|
139
67
|
json_attribute :strict_enumeration, as: :enumeration, values: %w{happy sad glad bad}, strict: true
|
140
68
|
json_attribute :strict_multi_enumeration, as: :enumeration, values: %w{happy sad glad bad}, multiple: true, strict: true
|
141
|
-
|
69
|
+
json_attribute :inspected_at, as: :datetime
|
70
|
+
json_attribute :finished_on, as: :date
|
71
|
+
json_attribute :cost, as: :decimal
|
72
|
+
embeds_one :entrance
|
73
|
+
embeds_one :main_entrance, class_name: 'Entrance'
|
142
74
|
embeds_many :restrooms
|
143
|
-
end
|
144
75
|
|
145
|
-
|
146
|
-
include ArDocStore::Model
|
147
|
-
attribute :name, :string
|
148
|
-
attribute :price, :float
|
149
|
-
attribute :approved_at, :datetime
|
76
|
+
validates :stories, numericality: { allow_nil: true }
|
150
77
|
end
|
78
|
+
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ar_doc_store
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Furber
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-09-
|
11
|
+
date: 2018-09-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '5.2'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '5.2'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: pg
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -66,6 +66,20 @@ dependencies:
|
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '10.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: simplecov
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
69
83
|
description: 'Provides an easy way to do something that is possible in Rails but still
|
70
84
|
a bit close to the metal using store_accessor: create typecasted, persistent attributes
|
71
85
|
that are not columns in the database but stored in the JSON "data" column. Also
|
@@ -83,32 +97,39 @@ files:
|
|
83
97
|
- Rakefile
|
84
98
|
- ar_doc_store.gemspec
|
85
99
|
- lib/ar_doc_store.rb
|
86
|
-
- lib/ar_doc_store/
|
87
|
-
- lib/ar_doc_store/
|
88
|
-
- lib/ar_doc_store/
|
89
|
-
- lib/ar_doc_store/
|
90
|
-
- lib/ar_doc_store/
|
91
|
-
- lib/ar_doc_store/
|
92
|
-
- lib/ar_doc_store/
|
93
|
-
- lib/ar_doc_store/
|
94
|
-
- lib/ar_doc_store/
|
95
|
-
- lib/ar_doc_store/
|
96
|
-
- lib/ar_doc_store/
|
100
|
+
- lib/ar_doc_store/attributes/array.rb
|
101
|
+
- lib/ar_doc_store/attributes/base.rb
|
102
|
+
- lib/ar_doc_store/attributes/boolean.rb
|
103
|
+
- lib/ar_doc_store/attributes/callback_support.rb
|
104
|
+
- lib/ar_doc_store/attributes/date.rb
|
105
|
+
- lib/ar_doc_store/attributes/datetime.rb
|
106
|
+
- lib/ar_doc_store/attributes/decimal.rb
|
107
|
+
- lib/ar_doc_store/attributes/embeds_base.rb
|
108
|
+
- lib/ar_doc_store/attributes/embeds_many.rb
|
109
|
+
- lib/ar_doc_store/attributes/embeds_one.rb
|
110
|
+
- lib/ar_doc_store/attributes/enumeration.rb
|
111
|
+
- lib/ar_doc_store/attributes/float.rb
|
112
|
+
- lib/ar_doc_store/attributes/integer.rb
|
113
|
+
- lib/ar_doc_store/attributes/string.rb
|
97
114
|
- lib/ar_doc_store/embeddable_model.rb
|
115
|
+
- lib/ar_doc_store/embedded_collection.rb
|
98
116
|
- lib/ar_doc_store/embedding.rb
|
99
117
|
- lib/ar_doc_store/model.rb
|
100
118
|
- lib/ar_doc_store/storage.rb
|
119
|
+
- lib/ar_doc_store/types/embeds_many.rb
|
120
|
+
- lib/ar_doc_store/types/embeds_one.rb
|
101
121
|
- lib/ar_doc_store/version.rb
|
102
|
-
- test/
|
103
|
-
- test/
|
104
|
-
- test/
|
105
|
-
- test/
|
106
|
-
- test/
|
107
|
-
- test/
|
108
|
-
- test/
|
109
|
-
- test/
|
110
|
-
- test/
|
111
|
-
- test/
|
122
|
+
- test/attributes/array_attribute_test.rb
|
123
|
+
- test/attributes/boolean_attribute_test.rb
|
124
|
+
- test/attributes/date_attribute_test.rb
|
125
|
+
- test/attributes/datetime_attribute_test.rb
|
126
|
+
- test/attributes/decimal_attribute_test.rb
|
127
|
+
- test/attributes/embeds_many_attribute_test.rb
|
128
|
+
- test/attributes/embeds_one_attribute_test.rb
|
129
|
+
- test/attributes/enumeration_attribute_test.rb
|
130
|
+
- test/attributes/float_attribute_test.rb
|
131
|
+
- test/attributes/integer_attribute_test.rb
|
132
|
+
- test/attributes/string_attribute_test.rb
|
112
133
|
- test/test_helper.rb
|
113
134
|
homepage: https://github.com/dfurber/ar_doc_store
|
114
135
|
licenses:
|
@@ -135,14 +156,15 @@ signing_key:
|
|
135
156
|
specification_version: 4
|
136
157
|
summary: A document storage gem meant for ActiveRecord PostgresQL JSON storage.
|
137
158
|
test_files:
|
138
|
-
- test/
|
139
|
-
- test/
|
140
|
-
- test/
|
141
|
-
- test/
|
142
|
-
- test/
|
143
|
-
- test/
|
144
|
-
- test/
|
145
|
-
- test/
|
146
|
-
- test/
|
147
|
-
- test/
|
159
|
+
- test/attributes/array_attribute_test.rb
|
160
|
+
- test/attributes/boolean_attribute_test.rb
|
161
|
+
- test/attributes/date_attribute_test.rb
|
162
|
+
- test/attributes/datetime_attribute_test.rb
|
163
|
+
- test/attributes/decimal_attribute_test.rb
|
164
|
+
- test/attributes/embeds_many_attribute_test.rb
|
165
|
+
- test/attributes/embeds_one_attribute_test.rb
|
166
|
+
- test/attributes/enumeration_attribute_test.rb
|
167
|
+
- test/attributes/float_attribute_test.rb
|
168
|
+
- test/attributes/integer_attribute_test.rb
|
169
|
+
- test/attributes/string_attribute_test.rb
|
148
170
|
- test/test_helper.rb
|
@@ -1,30 +0,0 @@
|
|
1
|
-
module ArDocStore
|
2
|
-
module AttributeTypes
|
3
|
-
|
4
|
-
class ArrayAttribute < BaseAttribute
|
5
|
-
|
6
|
-
def build
|
7
|
-
key = attribute.to_sym
|
8
|
-
default_value = default
|
9
|
-
model.class_eval do
|
10
|
-
store_accessor json_column, key
|
11
|
-
define_method key, -> {
|
12
|
-
value = read_store_attribute(json_column, key)
|
13
|
-
value or default_value
|
14
|
-
}
|
15
|
-
define_method "#{key}=".to_sym, -> (value) {
|
16
|
-
value = nil if value == ['']
|
17
|
-
write_store_attribute(json_column, key, value)
|
18
|
-
}
|
19
|
-
add_ransacker(key, 'text')
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
def type
|
24
|
-
:array
|
25
|
-
end
|
26
|
-
|
27
|
-
end
|
28
|
-
|
29
|
-
end
|
30
|
-
end
|
@@ -1,61 +0,0 @@
|
|
1
|
-
module ArDocStore
|
2
|
-
module AttributeTypes
|
3
|
-
class BaseAttribute
|
4
|
-
attr_accessor :conversion, :predicate, :options, :model, :attribute, :default
|
5
|
-
|
6
|
-
def self.build(model, attribute, options={})
|
7
|
-
new(model, attribute, options).build
|
8
|
-
end
|
9
|
-
|
10
|
-
def initialize(model, attribute, options)
|
11
|
-
@model, @attribute, @options = model, attribute, options
|
12
|
-
@model.virtual_attributes[attribute] = self
|
13
|
-
@default = options.delete(:default)
|
14
|
-
end
|
15
|
-
|
16
|
-
def build
|
17
|
-
store_attribute
|
18
|
-
end
|
19
|
-
|
20
|
-
#:nodoc:
|
21
|
-
def store_attribute
|
22
|
-
attribute = @attribute
|
23
|
-
predicate_method = predicate
|
24
|
-
default_value = default
|
25
|
-
dump_method = dump
|
26
|
-
load_method = load
|
27
|
-
model.class_eval do
|
28
|
-
add_ransacker(attribute, predicate_method)
|
29
|
-
define_method attribute.to_sym, -> {
|
30
|
-
value = read_store_attribute(json_column, attribute)
|
31
|
-
if value
|
32
|
-
value.public_send(load_method)
|
33
|
-
elsif default_value
|
34
|
-
write_default_store_attribute(attribute, default_value)
|
35
|
-
default_value
|
36
|
-
end
|
37
|
-
}
|
38
|
-
define_method "#{attribute}=".to_sym, -> (value) {
|
39
|
-
if value == '' || value.nil?
|
40
|
-
write_store_attribute json_column, attribute, nil
|
41
|
-
else
|
42
|
-
write_store_attribute(json_column, attribute, value.public_send(dump_method))
|
43
|
-
end
|
44
|
-
}
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
def conversion
|
49
|
-
:to_s
|
50
|
-
end
|
51
|
-
|
52
|
-
def dump
|
53
|
-
conversion
|
54
|
-
end
|
55
|
-
|
56
|
-
def load
|
57
|
-
conversion
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|