store_attribute 0.4.1 → 0.5.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.
- checksums.yaml +4 -4
- data/.travis.yml +2 -2
- data/Gemfile +1 -1
- data/README.md +11 -5
- data/gemfiles/{rails42.gemfile → rails5.gemfile} +1 -1
- data/lib/store_attribute/active_record/type/typed_store.rb +8 -23
- data/lib/store_attribute/version.rb +1 -1
- data/spec/spec_helper.rb +1 -2
- data/spec/store_attribute/typed_store_spec.rb +21 -21
- data/spec/support/money_type.rb +2 -2
- data/store_attribute.gemspec +2 -2
- metadata +8 -9
- data/gemfiles/rails-edge.gemfile +0 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cd2643cf4b1909497a0de3f0d15ed6ca51ba599e
|
4
|
+
data.tar.gz: 607171026ea9b9638e20a920b732bd7258db246a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 79e570bd455ecf0f2f7c500725e4a243f4e0d5133c5bdfd45100e10963bbe16623c37396d4a87b7018c74472813efbcfd212cc9d7ebe83c697ca00ad053d338c
|
7
|
+
data.tar.gz: 0c4458f32f0a658d276218894912e3c1c53833dd0cb4e506885bcff00a824beeadda620c89a4d6c09376edd1a262b9396ad317eb275c981d4d08194eb48968da
|
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -4,15 +4,21 @@
|
|
4
4
|
|
5
5
|
ActiveRecord extension which adds typecasting to store accessors.
|
6
6
|
|
7
|
-
Compatible with
|
7
|
+
Compatible with Rails 4.2 and Rails 5.
|
8
8
|
|
9
|
+
<a href="https://evilmartians.com/">
|
10
|
+
<img src="https://evilmartians.com/badges/sponsored-by-evil-martians.svg" alt="Sponsored by Evil Martians" width="236" height="54"></a>
|
9
11
|
|
10
12
|
### Install
|
11
13
|
|
12
14
|
In your Gemfile:
|
13
15
|
|
14
16
|
```ruby
|
15
|
-
|
17
|
+
# for Rails 5
|
18
|
+
gem "store_attribute", "~>0.5.0"
|
19
|
+
|
20
|
+
# for Rails 4.2
|
21
|
+
gem "store_attribute", "~>0.4.0"
|
16
22
|
```
|
17
23
|
|
18
24
|
### Usage
|
@@ -20,7 +26,7 @@ gem "store_attribute", "~>0.4.0" # version 0.4.x is for Rails 4.2.x and 0.5.x is
|
|
20
26
|
You can use `store_attribute` method to add additional accessors with a type to an existing store on a model.
|
21
27
|
|
22
28
|
```ruby
|
23
|
-
|
29
|
+
store_attribute(store_name, name, type, options = {})
|
24
30
|
```
|
25
31
|
|
26
32
|
Where:
|
@@ -62,7 +68,7 @@ u.settings['ration'] = "3.141592653"
|
|
62
68
|
u.ratio # => "3.141592653"
|
63
69
|
|
64
70
|
# On the other hand, writing through accessor set correct data within store
|
65
|
-
u.ratio = "3.
|
71
|
+
u.ratio = "3.141592653"
|
66
72
|
u.ratio # => 3
|
67
73
|
u.settings['ratio'] # => 3
|
68
74
|
```
|
@@ -81,4 +87,4 @@ Or through `store`:
|
|
81
87
|
class User < ActiveRecord::Base
|
82
88
|
store :settings, accessors: [:color, :homepage, login_at: :datetime], coder: JSON
|
83
89
|
end
|
84
|
-
```
|
90
|
+
```
|
@@ -2,21 +2,6 @@ require 'active_record/type'
|
|
2
2
|
|
3
3
|
module ActiveRecord
|
4
4
|
module Type # :nodoc:
|
5
|
-
BASE_TYPES = {
|
6
|
-
boolean: ::ActiveRecord::Type::Boolean,
|
7
|
-
integer: ::ActiveRecord::Type::Integer,
|
8
|
-
string: ::ActiveRecord::Type::String,
|
9
|
-
float: ::ActiveRecord::Type::Float,
|
10
|
-
date: ::ActiveRecord::Type::Date,
|
11
|
-
datetime: ::ActiveRecord::Type::DateTime,
|
12
|
-
decimal: ::ActiveRecord::Type::Decimal
|
13
|
-
}.freeze
|
14
|
-
|
15
|
-
def self.lookup_type(type, options)
|
16
|
-
BASE_TYPES[type.to_sym].try(:new, options) ||
|
17
|
-
ActiveRecord::Base.connection.type_map.lookup(type.to_s, options)
|
18
|
-
end
|
19
|
-
|
20
5
|
class TypedStore < DelegateClass(ActiveRecord::Type::Value) # :nodoc:
|
21
6
|
# Creates +TypedStore+ type instance and specifies type caster
|
22
7
|
# for key.
|
@@ -33,26 +18,26 @@ module ActiveRecord
|
|
33
18
|
end
|
34
19
|
|
35
20
|
def add_typed_key(key, type, **options)
|
36
|
-
type = Type.
|
21
|
+
type = ActiveRecord::Type.lookup(type, options) if type.is_a?(Symbol)
|
37
22
|
@accessor_types[key.to_s] = type
|
38
23
|
end
|
39
24
|
|
40
|
-
def
|
25
|
+
def deserialize(value)
|
41
26
|
hash = super
|
42
27
|
if hash
|
43
28
|
accessor_types.each do |key, type|
|
44
|
-
hash[key] = type.
|
29
|
+
hash[key] = type.deserialize(hash[key]) if hash.key?(key)
|
45
30
|
end
|
46
31
|
end
|
47
32
|
hash
|
48
33
|
end
|
49
34
|
|
50
|
-
def
|
35
|
+
def serialize(value)
|
51
36
|
if value.is_a?(Hash)
|
52
37
|
typed_casted = {}
|
53
38
|
accessor_types.each do |key, type|
|
54
39
|
k = key_to_cast(value, key)
|
55
|
-
typed_casted[k] = type.
|
40
|
+
typed_casted[k] = type.serialize(value[k]) unless k.nil?
|
56
41
|
end
|
57
42
|
super(value.merge(typed_casted))
|
58
43
|
else
|
@@ -60,11 +45,11 @@ module ActiveRecord
|
|
60
45
|
end
|
61
46
|
end
|
62
47
|
|
63
|
-
def
|
48
|
+
def cast(value)
|
64
49
|
hash = super
|
65
50
|
if hash
|
66
51
|
accessor_types.each do |key, type|
|
67
|
-
hash[key] = type.
|
52
|
+
hash[key] = type.cast(hash[key]) if hash.key?(key)
|
68
53
|
end
|
69
54
|
end
|
70
55
|
hash
|
@@ -75,7 +60,7 @@ module ActiveRecord
|
|
75
60
|
end
|
76
61
|
|
77
62
|
def write(object, attribute, key, value)
|
78
|
-
value = type_for(key).
|
63
|
+
value = type_for(key).cast(value) if typed?(key)
|
79
64
|
store_accessor.write(object, attribute, key, value)
|
80
65
|
end
|
81
66
|
|
data/spec/spec_helper.rb
CHANGED
@@ -31,8 +31,7 @@ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
|
|
31
31
|
RSpec.configure do |config|
|
32
32
|
config.mock_with :rspec
|
33
33
|
|
34
|
-
config.
|
35
|
-
config.run_all_when_everything_filtered = true
|
34
|
+
config.filter_run_when_matching :focus
|
36
35
|
|
37
36
|
config.example_status_persistence_file_path = "tmp/rspec_examples.txt"
|
38
37
|
|
@@ -14,51 +14,51 @@ describe ActiveRecord::Type::TypedStore do
|
|
14
14
|
context "with json store" do
|
15
15
|
subject { described_class.new(json_type) }
|
16
16
|
|
17
|
-
describe "#
|
17
|
+
describe "#cast" do
|
18
18
|
it "without key types", :aggregate_failures do
|
19
|
-
expect(subject.
|
20
|
-
expect(subject.
|
19
|
+
expect(subject.cast([1, 2])).to eq [1, 2]
|
20
|
+
expect(subject.cast('a' => 'b')).to eq('a' => 'b')
|
21
21
|
end
|
22
22
|
|
23
23
|
it "with type keys" do
|
24
24
|
subject.add_typed_key('date', :date)
|
25
25
|
|
26
26
|
date = ::Date.new(2016, 6, 22)
|
27
|
-
expect(subject.
|
27
|
+
expect(subject.cast(date: '2016-06-22')).to eq('date' => date)
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
31
|
-
describe "#
|
31
|
+
describe "#deserialize" do
|
32
32
|
it "without key types", :aggregate_failures do
|
33
|
-
expect(subject.
|
34
|
-
expect(subject.
|
33
|
+
expect(subject.deserialize('[1,2]')).to eq [1, 2]
|
34
|
+
expect(subject.deserialize('{"a":"b"}')).to eq('a' => 'b')
|
35
35
|
end
|
36
36
|
|
37
37
|
it "with type keys" do
|
38
38
|
subject.add_typed_key('date', :date)
|
39
39
|
|
40
40
|
date = ::Date.new(2016, 6, 22)
|
41
|
-
expect(subject.
|
41
|
+
expect(subject.deserialize('{"date":"2016-06-22"}')).to eq('date' => date)
|
42
42
|
end
|
43
43
|
end
|
44
44
|
|
45
|
-
describe "#
|
45
|
+
describe "#serialize" do
|
46
46
|
it "without key types", :aggregate_failures do
|
47
|
-
expect(subject.
|
48
|
-
expect(subject.
|
47
|
+
expect(subject.serialize([1, 2])).to eq '[1,2]'
|
48
|
+
expect(subject.serialize('a' => 'b')).to eq '{"a":"b"}'
|
49
49
|
end
|
50
50
|
|
51
51
|
it "with type keys" do
|
52
52
|
subject.add_typed_key('date', :date)
|
53
53
|
|
54
54
|
date = ::Date.new(2016, 6, 22)
|
55
|
-
expect(subject.
|
55
|
+
expect(subject.serialize(date: date)).to eq '{"date":"2016-06-22"}'
|
56
56
|
end
|
57
57
|
|
58
58
|
it "with type key with option" do
|
59
59
|
subject.add_typed_key('val', :integer, limit: 1)
|
60
60
|
|
61
|
-
expect { subject.
|
61
|
+
expect { subject.serialize(val: 1024) }.to raise_error(RangeError)
|
62
62
|
end
|
63
63
|
end
|
64
64
|
|
@@ -69,8 +69,8 @@ describe ActiveRecord::Type::TypedStore do
|
|
69
69
|
|
70
70
|
date = ::Date.new(2016, 6, 22)
|
71
71
|
|
72
|
-
expect(type.
|
73
|
-
expect(new_type.
|
72
|
+
expect(type.cast(date: '2016-06-22', val: '1.2')).to eq('date' => date, 'val' => '1.2')
|
73
|
+
expect(new_type.cast(date: '2016-06-22', val: '1.2')).to eq('date' => date, 'val' => 1)
|
74
74
|
end
|
75
75
|
end
|
76
76
|
end
|
@@ -83,12 +83,12 @@ describe ActiveRecord::Type::TypedStore do
|
|
83
83
|
|
84
84
|
date = ::Date.new(2016, 6, 22)
|
85
85
|
|
86
|
-
expect(subject.
|
87
|
-
expect(subject.
|
88
|
-
expect(subject.
|
89
|
-
expect(subject.
|
90
|
-
expect(subject.
|
91
|
-
expect(subject.
|
86
|
+
expect(subject.cast(date: '2016-06-22')).to eq('date' => date)
|
87
|
+
expect(subject.cast('date' => '2016-06-22')).to eq('date' => date)
|
88
|
+
expect(subject.deserialize("---\n:date: 2016-06-22\n")).to eq('date' => date)
|
89
|
+
expect(subject.deserialize("---\ndate: 2016-06-22\n")).to eq('date' => date)
|
90
|
+
expect(subject.serialize(date: date)).to eq "--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess\ndate: 2016-06-22\n"
|
91
|
+
expect(subject.serialize('date' => date)).to eq "--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess\ndate: 2016-06-22\n"
|
92
92
|
end
|
93
93
|
end
|
94
94
|
end
|
data/spec/support/money_type.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
class MoneyType < ActiveRecord::Type::Integer
|
2
|
-
def
|
2
|
+
def cast(value)
|
3
3
|
if !value.is_a?(Numeric) && value.include?('$')
|
4
4
|
price_in_dollars = value.delete('$').to_f
|
5
5
|
super(price_in_dollars * 100)
|
@@ -9,4 +9,4 @@ class MoneyType < ActiveRecord::Type::Integer
|
|
9
9
|
end
|
10
10
|
end
|
11
11
|
|
12
|
-
ActiveRecord::
|
12
|
+
ActiveRecord::Type.register(:money_type, MoneyType)
|
data/store_attribute.gemspec
CHANGED
@@ -17,11 +17,11 @@ Gem::Specification.new do |s|
|
|
17
17
|
s.files = `git ls-files`.split($/)
|
18
18
|
s.require_paths = ["lib"]
|
19
19
|
|
20
|
-
s.add_runtime_dependency "activerecord", "
|
20
|
+
s.add_runtime_dependency "activerecord", "~>5.0.0"
|
21
21
|
|
22
22
|
s.add_development_dependency "pg", "~>0.18"
|
23
23
|
s.add_development_dependency "rake", "~> 10.1"
|
24
24
|
s.add_development_dependency "simplecov", ">= 0.3.8"
|
25
25
|
s.add_development_dependency "pry-byebug"
|
26
|
-
s.add_development_dependency "rspec", "~> 3.
|
26
|
+
s.add_development_dependency "rspec", "~> 3.5.0"
|
27
27
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: store_attribute
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- palkan
|
@@ -14,16 +14,16 @@ dependencies:
|
|
14
14
|
name: activerecord
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 5.0.0
|
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.0.0
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: pg
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -86,14 +86,14 @@ dependencies:
|
|
86
86
|
requirements:
|
87
87
|
- - "~>"
|
88
88
|
- !ruby/object:Gem::Version
|
89
|
-
version: 3.
|
89
|
+
version: 3.5.0
|
90
90
|
type: :development
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
94
|
- - "~>"
|
95
95
|
- !ruby/object:Gem::Version
|
96
|
-
version: 3.
|
96
|
+
version: 3.5.0
|
97
97
|
description: ActiveRecord extension which adds typecasting to store accessors
|
98
98
|
email:
|
99
99
|
- dementiev.vm@gmail.com
|
@@ -113,8 +113,7 @@ files:
|
|
113
113
|
- bench/setup.rb
|
114
114
|
- bin/console
|
115
115
|
- bin/setup
|
116
|
-
- gemfiles/
|
117
|
-
- gemfiles/rails42.gemfile
|
116
|
+
- gemfiles/rails5.gemfile
|
118
117
|
- lib/store_attribute.rb
|
119
118
|
- lib/store_attribute/active_record.rb
|
120
119
|
- lib/store_attribute/active_record/store.rb
|