activerecord-typedstore 1.0.0.beta1 → 1.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
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ed8f250e16de47101a01c8633fb6587e58626ee0
|
4
|
+
data.tar.gz: e5dd919d347fb854e5d03f8aac3786f334645a15
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5cce7b2e70c3abf6df76ca6007c3d21e072f38b34a1d281fda28bdb514d2eb30bad2e2e9564833c28e82e8232fe68a8af5389211e4ac28f63b549a2005baf13e
|
7
|
+
data.tar.gz: 3a6498ef57cd94fcf86120c59ce5f8d40a006c4740e30f90d8b25e8482fa1bcb59ce857e2258e2eb9938e2ec9b2362251f9a3657d1a85e0654d23004008224a0
|
@@ -6,6 +6,8 @@ module ActiveRecord::TypedStore
|
|
6
6
|
|
7
7
|
def initialize(options)
|
8
8
|
@coder = options.fetch(:coder) { default_coder }
|
9
|
+
@accessors = options[:accessors]
|
10
|
+
@accessors = [] if options[:accessors] == false
|
9
11
|
@fields = {}
|
10
12
|
yield self
|
11
13
|
end
|
@@ -15,7 +17,7 @@ module ActiveRecord::TypedStore
|
|
15
17
|
end
|
16
18
|
|
17
19
|
def accessors
|
18
|
-
@fields.values.select
|
20
|
+
@accessors || @fields.values.select(&:accessor).map(&:name)
|
19
21
|
end
|
20
22
|
|
21
23
|
delegate :keys, to: :@fields
|
@@ -18,7 +18,7 @@ module ActiveRecord::TypedStore
|
|
18
18
|
|
19
19
|
def typed_store(store_attribute, options={}, &block)
|
20
20
|
dsl = DSL.new(options, &block)
|
21
|
-
self.typed_stores
|
21
|
+
self.typed_stores ||= {}
|
22
22
|
self.typed_stores[store_attribute] = dsl
|
23
23
|
|
24
24
|
typed_klass = TypedHash.create(dsl.fields.values)
|
@@ -526,6 +526,16 @@ shared_examples 'a store' do |retain_type=true|
|
|
526
526
|
stores = model.class.typed_stores
|
527
527
|
expect(stores[:settings].keys).to eq [:no_default, :name, :email, :cell_phone, :public, :enabled, :age, :max_length, :rate, :price, :published_on, :remind_on, :published_at, :remind_at, :total_price, :shipping_cost, :grades, :tags, :nickname, :author, :source, :signup, :country]
|
528
528
|
end
|
529
|
+
|
530
|
+
it "can access keys even when accessors are not defined" do
|
531
|
+
stores = model.class.typed_stores
|
532
|
+
expect(stores[:explicit_settings].keys).to eq [:ip_address, :user_agent, :signup]
|
533
|
+
end
|
534
|
+
|
535
|
+
it "can access keys even when accessors are partially defined" do
|
536
|
+
stores = model.class.typed_stores
|
537
|
+
expect(stores[:partial_settings].keys).to eq [:tax_rate_key, :tax_rate]
|
538
|
+
end
|
529
539
|
end
|
530
540
|
|
531
541
|
it 'does not include blank attribute' do
|
@@ -645,6 +655,43 @@ shared_examples 'a store' do |retain_type=true|
|
|
645
655
|
|
646
656
|
end
|
647
657
|
|
658
|
+
describe 'with no accessors' do
|
659
|
+
|
660
|
+
it 'cannot be accessed as a model attribute' do
|
661
|
+
expect(model).not_to respond_to :ip_address
|
662
|
+
expect(model).not_to respond_to :ip_address=
|
663
|
+
end
|
664
|
+
|
665
|
+
it 'cannot be queried' do
|
666
|
+
expect(model).not_to respond_to :ip_address?
|
667
|
+
end
|
668
|
+
|
669
|
+
it 'cannot be reset' do
|
670
|
+
expect(model).not_to respond_to :reset_ip_address!
|
671
|
+
end
|
672
|
+
|
673
|
+
it 'does not have dirty accessors' do
|
674
|
+
expect(model).not_to respond_to :ip_address_was
|
675
|
+
end
|
676
|
+
|
677
|
+
it 'still has casting a default handling' do
|
678
|
+
expect(model.explicit_settings[:ip_address]).to be == '127.0.0.1'
|
679
|
+
end
|
680
|
+
|
681
|
+
end
|
682
|
+
|
683
|
+
describe 'with some accessors' do
|
684
|
+
|
685
|
+
it 'does not define an attribute' do
|
686
|
+
expect(model).not_to respond_to :tax_rate_key
|
687
|
+
end
|
688
|
+
|
689
|
+
it 'define an attribute when included in the accessors array' do
|
690
|
+
expect(model).to respond_to :tax_rate
|
691
|
+
end
|
692
|
+
|
693
|
+
end
|
694
|
+
|
648
695
|
describe '`any` attributes' do
|
649
696
|
|
650
697
|
it 'accept any type' do
|
@@ -666,6 +713,12 @@ shared_examples 'a store' do |retain_type=true|
|
|
666
713
|
expect(model.settings[:signup][:counter]).to eq 123
|
667
714
|
end
|
668
715
|
|
716
|
+
it 'works with default hash without affecting unaccessible attributes' do
|
717
|
+
model.signup[:counter] = 123
|
718
|
+
model.save!
|
719
|
+
expect(model.explicit_settings[:signup][:counter]).to be_nil
|
720
|
+
end
|
721
|
+
|
669
722
|
end
|
670
723
|
end
|
671
724
|
|
data/spec/support/models.rb
CHANGED
@@ -51,12 +51,29 @@ def define_columns(t)
|
|
51
51
|
t.string :nickname, blank: false, default: 'Please enter your nickname'
|
52
52
|
end
|
53
53
|
|
54
|
-
def
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
54
|
+
def define_store_with_no_attributes(**options)
|
55
|
+
typed_store :explicit_settings, accessors: false, **options do |t|
|
56
|
+
t.string :ip_address, default: '127.0.0.1'
|
57
|
+
t.string :user_agent
|
58
|
+
t.any :signup, default: {}
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def define_store_with_partial_attributes(**options)
|
63
|
+
typed_store :partial_settings, accessors: [:tax_rate], **options do |t|
|
64
|
+
t.string :tax_rate_key
|
65
|
+
t.string :tax_rate
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def define_store_with_attributes(**options)
|
70
|
+
typed_store :settings, **options do |t|
|
71
|
+
define_columns(t)
|
72
|
+
t.any :author
|
73
|
+
t.any :source, blank: false, default: 'web'
|
74
|
+
t.any :signup, default: {}
|
75
|
+
t.string :country, blank: false, default: 'Canada', accessor: false
|
76
|
+
end
|
60
77
|
end
|
61
78
|
|
62
79
|
class CreateAllTables < ActiveRecord::Migration
|
@@ -89,9 +106,9 @@ class CreateAllTables < ActiveRecord::Migration
|
|
89
106
|
|
90
107
|
ActiveRecord::Base.establish_connection(:test_sqlite3)
|
91
108
|
recreate_table(:sqlite3_regular_ar_models) { |t| define_columns(t); t.text :untyped_settings }
|
92
|
-
recreate_table(:yaml_typed_store_models) { |t| t.text :settings; t.text :untyped_settings }
|
93
|
-
recreate_table(:json_typed_store_models) { |t| t.text :settings; t.text :untyped_settings }
|
94
|
-
recreate_table(:marshal_typed_store_models) { |t| t.text :settings; t.text :untyped_settings }
|
109
|
+
recreate_table(:yaml_typed_store_models) { |t| t.text :settings; t.text :explicit_settings; t.text :partial_settings; t.text :untyped_settings }
|
110
|
+
recreate_table(:json_typed_store_models) { |t| t.text :settings; t.text :explicit_settings; t.text :partial_settings; t.text :untyped_settings }
|
111
|
+
recreate_table(:marshal_typed_store_models) { |t| t.text :settings; t.text :explicit_settings; t.text :partial_settings; t.text :untyped_settings }
|
95
112
|
end
|
96
113
|
end
|
97
114
|
ActiveRecord::Migration.verbose = true
|
@@ -147,9 +164,10 @@ if ENV['POSTGRES']
|
|
147
164
|
class PostgresHstoreTypedStoreModel < ActiveRecord::Base
|
148
165
|
establish_connection ENV['POSTGRES_URL'] || :test_postgresql
|
149
166
|
store :untyped_settings, accessors: [:title]
|
150
|
-
|
151
|
-
|
152
|
-
|
167
|
+
|
168
|
+
define_store_with_attributes(coder: ColumnCoder.new(AsJson))
|
169
|
+
define_store_with_no_attributes(coder: ColumnCoder.new(AsJson))
|
170
|
+
define_store_with_partial_attributes(coder: ColumnCoder.new(AsJson))
|
153
171
|
end
|
154
172
|
|
155
173
|
if ENV['POSTGRES_JSON']
|
@@ -159,9 +177,10 @@ if ENV['POSTGRES']
|
|
159
177
|
class PostgresJsonTypedStoreModel < ActiveRecord::Base
|
160
178
|
establish_connection ENV['POSTGRES_URL'] || :test_postgresql
|
161
179
|
store :untyped_settings, accessors: [:title]
|
162
|
-
|
163
|
-
|
164
|
-
|
180
|
+
|
181
|
+
define_store_with_attributes(coder: false)
|
182
|
+
define_store_with_no_attributes(coder: false)
|
183
|
+
define_store_with_partial_attributes(coder: false)
|
165
184
|
end
|
166
185
|
|
167
186
|
else
|
@@ -169,9 +188,10 @@ if ENV['POSTGRES']
|
|
169
188
|
class PostgresJsonTypedStoreModel < ActiveRecord::Base
|
170
189
|
establish_connection ENV['POSTGRES_URL'] || :test_postgresql
|
171
190
|
store :untyped_settings, accessors: [:title]
|
172
|
-
|
173
|
-
|
174
|
-
|
191
|
+
|
192
|
+
define_store_with_attributes(coder: ColumnCoder.new(AsJson))
|
193
|
+
define_store_with_no_attributes(coder: ColumnCoder.new(AsJson))
|
194
|
+
define_store_with_partial_attributes(coder: ColumnCoder.new(AsJson))
|
175
195
|
end
|
176
196
|
|
177
197
|
end
|
@@ -189,17 +209,19 @@ end
|
|
189
209
|
class YamlTypedStoreModel < ActiveRecord::Base
|
190
210
|
establish_connection :test_sqlite3
|
191
211
|
store :untyped_settings, accessors: [:title]
|
192
|
-
|
193
|
-
|
194
|
-
|
212
|
+
|
213
|
+
define_store_with_attributes
|
214
|
+
define_store_with_no_attributes
|
215
|
+
define_store_with_partial_attributes
|
195
216
|
end
|
196
217
|
|
197
218
|
class JsonTypedStoreModel < ActiveRecord::Base
|
198
219
|
establish_connection :test_sqlite3
|
199
220
|
store :untyped_settings, accessors: [:title]
|
200
|
-
|
201
|
-
|
202
|
-
|
221
|
+
|
222
|
+
define_store_with_attributes(coder: ColumnCoder.new(JSON))
|
223
|
+
define_store_with_no_attributes(coder: ColumnCoder.new(JSON))
|
224
|
+
define_store_with_partial_attributes(coder: ColumnCoder.new(JSON))
|
203
225
|
end
|
204
226
|
|
205
227
|
module MarshalCoder
|
@@ -219,9 +241,10 @@ end
|
|
219
241
|
class MarshalTypedStoreModel < ActiveRecord::Base
|
220
242
|
establish_connection :test_sqlite3
|
221
243
|
store :untyped_settings, accessors: [:title]
|
222
|
-
|
223
|
-
|
224
|
-
|
244
|
+
|
245
|
+
define_store_with_attributes(coder: ColumnCoder.new(MarshalCoder))
|
246
|
+
define_store_with_no_attributes(coder: ColumnCoder.new(MarshalCoder))
|
247
|
+
define_store_with_partial_attributes(coder: ColumnCoder.new(MarshalCoder))
|
225
248
|
end
|
226
249
|
|
227
250
|
Models = [
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: activerecord-typedstore
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.0
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jean Boussier
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-06-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -190,12 +190,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
190
190
|
version: '0'
|
191
191
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
192
192
|
requirements:
|
193
|
-
- - "
|
193
|
+
- - ">="
|
194
194
|
- !ruby/object:Gem::Version
|
195
|
-
version:
|
195
|
+
version: '0'
|
196
196
|
requirements: []
|
197
197
|
rubyforge_project:
|
198
|
-
rubygems_version: 2.
|
198
|
+
rubygems_version: 2.5.1
|
199
199
|
signing_key:
|
200
200
|
specification_version: 4
|
201
201
|
summary: Add type casting and full method attributes support to RctiveRecord store
|