ar_doc_store 1.0.5 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/ar_doc_store.gemspec +3 -3
  3. data/lib/ar_doc_store.rb +30 -28
  4. data/lib/ar_doc_store/attributes/array.rb +25 -0
  5. data/lib/ar_doc_store/attributes/base.rb +72 -0
  6. data/lib/ar_doc_store/attributes/boolean.rb +17 -0
  7. data/lib/ar_doc_store/attributes/callback_support.rb +21 -0
  8. data/lib/ar_doc_store/attributes/date.rb +21 -0
  9. data/lib/ar_doc_store/attributes/datetime.rb +21 -0
  10. data/lib/ar_doc_store/attributes/decimal.rb +17 -0
  11. data/lib/ar_doc_store/attributes/embeds_base.rb +35 -0
  12. data/lib/ar_doc_store/attributes/embeds_many.rb +143 -0
  13. data/lib/ar_doc_store/{attribute_types/embeds_one_attribute.rb → attributes/embeds_one.rb} +25 -30
  14. data/lib/ar_doc_store/{attribute_types/enumeration_attribute.rb → attributes/enumeration.rb} +2 -6
  15. data/lib/ar_doc_store/{attribute_types/float_attribute.rb → attributes/float.rb} +5 -8
  16. data/lib/ar_doc_store/{attribute_types/integer_attribute.rb → attributes/integer.rb} +5 -8
  17. data/lib/ar_doc_store/attributes/string.rb +13 -0
  18. data/lib/ar_doc_store/embeddable_model.rb +51 -75
  19. data/lib/ar_doc_store/embedded_collection.rb +14 -0
  20. data/lib/ar_doc_store/embedding.rb +0 -2
  21. data/lib/ar_doc_store/model.rb +18 -8
  22. data/lib/ar_doc_store/storage.rb +4 -127
  23. data/lib/ar_doc_store/types/embeds_many.rb +52 -0
  24. data/lib/ar_doc_store/types/embeds_one.rb +42 -0
  25. data/lib/ar_doc_store/version.rb +1 -1
  26. data/test/{attribute_types → attributes}/array_attribute_test.rb +5 -1
  27. data/test/{attribute_types → attributes}/boolean_attribute_test.rb +7 -1
  28. data/test/attributes/date_attribute_test.rb +52 -0
  29. data/test/attributes/datetime_attribute_test.rb +54 -0
  30. data/test/attributes/decimal_attribute_test.rb +38 -0
  31. data/test/attributes/embeds_many_attribute_test.rb +78 -0
  32. data/test/attributes/embeds_one_attribute_test.rb +80 -0
  33. data/test/{attribute_types → attributes}/enumeration_attribute_test.rb +5 -0
  34. data/test/{attribute_types → attributes}/float_attribute_test.rb +6 -1
  35. data/test/attributes/integer_attribute_test.rb +63 -0
  36. data/test/{attribute_types → attributes}/string_attribute_test.rb +6 -0
  37. data/test/test_helper.rb +22 -94
  38. metadata +57 -35
  39. data/lib/ar_doc_store/attribute_types/array_attribute.rb +0 -30
  40. data/lib/ar_doc_store/attribute_types/base_attribute.rb +0 -61
  41. data/lib/ar_doc_store/attribute_types/boolean_attribute.rb +0 -25
  42. data/lib/ar_doc_store/attribute_types/datetime_attribute.rb +0 -17
  43. data/lib/ar_doc_store/attribute_types/embeds_many_attribute.rb +0 -165
  44. data/lib/ar_doc_store/attribute_types/string_attribute.rb +0 -17
  45. data/lib/ar_doc_store/attribute_types/uuid_attribute.rb +0 -30
  46. data/test/attribute_types/datetime_attribute_test.rb +0 -35
  47. data/test/attribute_types/integer_attribute_test.rb +0 -33
  48. data/test/originals/dirty_attributes_test.rb +0 -35
  49. data/test/originals/embedded_model_attribute_test.rb +0 -23
  50. 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
@@ -24,4 +24,10 @@ class StringAttributeTest < MiniTest::Test
24
24
  assert_equal '51', b.name
25
25
  end
26
26
 
27
+ def test_persistence
28
+ b = Building.new name: 'Test', stories: 5
29
+ assert b.save
30
+ assert_equal 'Test', Building.find(b.id).name
31
+ end
32
+
27
33
  end
@@ -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
- # A building has many entrances and restrooms and some fields of its own
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
- class EmptyModel
64
- include ArDocStore::EmbeddableModel
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
- class EmbeddableA < ARDuck
73
- include ArDocStore::EmbeddableModel
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
- embeds_one :route
109
- embeds_one :door
48
+ json_attribute :name
110
49
  end
111
50
 
112
51
  class Restroom
113
52
  include ArDocStore::EmbeddableModel
114
- embeds_one :route
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
- embeds_many :entrances
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
- class PurchaseOrder < ActiveRecord::Base
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: 1.0.5
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-10 00:00:00.000000000 Z
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: '0'
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: '0'
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/attribute_types/array_attribute.rb
87
- - lib/ar_doc_store/attribute_types/base_attribute.rb
88
- - lib/ar_doc_store/attribute_types/boolean_attribute.rb
89
- - lib/ar_doc_store/attribute_types/datetime_attribute.rb
90
- - lib/ar_doc_store/attribute_types/embeds_many_attribute.rb
91
- - lib/ar_doc_store/attribute_types/embeds_one_attribute.rb
92
- - lib/ar_doc_store/attribute_types/enumeration_attribute.rb
93
- - lib/ar_doc_store/attribute_types/float_attribute.rb
94
- - lib/ar_doc_store/attribute_types/integer_attribute.rb
95
- - lib/ar_doc_store/attribute_types/string_attribute.rb
96
- - lib/ar_doc_store/attribute_types/uuid_attribute.rb
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/attribute_types/array_attribute_test.rb
103
- - test/attribute_types/boolean_attribute_test.rb
104
- - test/attribute_types/datetime_attribute_test.rb
105
- - test/attribute_types/enumeration_attribute_test.rb
106
- - test/attribute_types/float_attribute_test.rb
107
- - test/attribute_types/integer_attribute_test.rb
108
- - test/attribute_types/string_attribute_test.rb
109
- - test/originals/dirty_attributes_test.rb
110
- - test/originals/embedded_model_attribute_test.rb
111
- - test/originals/embedding_test.rb
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/attribute_types/array_attribute_test.rb
139
- - test/attribute_types/boolean_attribute_test.rb
140
- - test/attribute_types/datetime_attribute_test.rb
141
- - test/attribute_types/enumeration_attribute_test.rb
142
- - test/attribute_types/float_attribute_test.rb
143
- - test/attribute_types/integer_attribute_test.rb
144
- - test/attribute_types/string_attribute_test.rb
145
- - test/originals/dirty_attributes_test.rb
146
- - test/originals/embedded_model_attribute_test.rb
147
- - test/originals/embedding_test.rb
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