store_attribute 0.4.1 → 0.5.3

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
- SHA1:
3
- metadata.gz: 5b686f8993ef12feb2c0a1b36dcf90fbf0a7225b
4
- data.tar.gz: 5498a60d8e4ac7ce66e4316b5fe2dfb50856c662
2
+ SHA256:
3
+ metadata.gz: 26bfe00fc2e06215356a2e050700f0d257e56401249c97487e26f58133f4ea0e
4
+ data.tar.gz: 5e9ba6def76cf0f0aa77130db602929da9725f1483508e244557e90e8bd22892
5
5
  SHA512:
6
- metadata.gz: b41a03c88333430a322a2b0147b445284c4335063fcfaccaae53200b8438cad9a22996b1951df936da18fbbde23bd57d06847a49042971346896e181a9729e86
7
- data.tar.gz: eb62f09e1f44a05d3d29540ac9b7f4751d226c0b4f37e6c92cc7b1c285c7cf993e16585e3f33edae18d2170f6544ac30f810590d8ac3a0fd23f1df124fed1ec6
6
+ metadata.gz: 3de11ae80f51e606826b3dbbdd92afa4a7443ec24ef595c616908adb23f2588908052f5db52d963164843aa0868c30747b54921e9fdac2b7deaede4b770413b3
7
+ data.tar.gz: 6032541f1dd51712f9755b9ca8ccfa25b145c670d319a3dde909917fb0b7447069600a3fdd7c8fce40e131733fa6495e7be420f7a77aa5f60a88c36c28301f3a
data/.rubocop.yml CHANGED
@@ -1,51 +1,54 @@
1
+ require:
2
+ - standard/cop/semantic_blocks
3
+ - rubocop-md
4
+
5
+ inherit_gem:
6
+ standard: config/base.yml
7
+
1
8
  AllCops:
2
- # Include gemspec and Rakefile
3
- Include:
4
- - 'lib/**/*.rb'
5
- - 'lib/**/*.rake'
6
- - 'spec/**/*.rb'
7
9
  Exclude:
8
- - 'bin/**/*'
9
- - 'spec/dummy/**/*'
10
+ - 'bin/*'
10
11
  - 'tmp/**/*'
12
+ - 'Gemfile'
13
+ - 'vendor/**/*'
14
+ - 'gemfiles/**/*'
11
15
  - 'bench/**/*'
12
16
  DisplayCopNames: true
13
- StyleGuideCopsOnly: false
17
+ TargetRubyVersion: 2.4
14
18
 
15
- Style/AccessorMethodName:
19
+ Standard/SemanticBlocks:
16
20
  Enabled: false
17
21
 
18
- Style/TrivialAccessors:
19
- Enabled: false
22
+ Style/FrozenStringLiteralComment:
23
+ Enabled: true
20
24
 
21
- Style/Documentation:
22
- Exclude:
23
- - 'spec/**/*.rb'
25
+ Style/TrailingCommaInArrayLiteral:
26
+ EnforcedStyleForMultiline: no_comma
24
27
 
25
- Style/StringLiterals:
26
- Enabled: false
28
+ Style/TrailingCommaInHashLiteral:
29
+ EnforcedStyleForMultiline: no_comma
27
30
 
28
- Style/SpaceInsideStringInterpolation:
29
- EnforcedStyle: no_space
31
+ Layout/AlignParameters:
32
+ EnforcedStyle: with_first_parameter
30
33
 
31
- Style/BlockDelimiters:
34
+ Lint/Void:
32
35
  Exclude:
33
- - 'spec/**/*.rb'
36
+ - '**/*.md'
34
37
 
35
- Lint/AmbiguousRegexpLiteral:
36
- Enabled: false
37
-
38
- Metrics/MethodLength:
38
+ # See https://github.com/rubocop-hq/rubocop/issues/4222
39
+ Lint/AmbiguousBlockAssociation:
39
40
  Exclude:
40
- - 'spec/**/*.rb'
41
+ - 'spec/**/*'
42
+ - '**/*.md'
41
43
 
42
- Metrics/LineLength:
43
- Max: 100
44
+ Lint/DuplicateMethods:
44
45
  Exclude:
45
- - 'spec/**/*.rb'
46
+ - '**/*.md'
46
47
 
47
- Rails/Date:
48
- Enabled: false
48
+ Naming/FileName:
49
+ Exclude:
50
+ - '**/*.md'
49
51
 
50
- Rails/TimeZone:
51
- Enabled: false
52
+ Layout/InitialIndentation:
53
+ Exclude:
54
+ - 'CHANGELOG.md'
data/.travis.yml CHANGED
@@ -10,5 +10,12 @@ before_script:
10
10
 
11
11
  matrix:
12
12
  include:
13
- - rvm: 2.3.0
14
- gemfile: gemfiles/rails42.gemfile
13
+ - rvm: 2.4.1
14
+ gemfile: gemfiles/rails5.gemfile
15
+ - rvm: 2.6.2
16
+ gemfile: gemfiles/rails6.gemfile
17
+ - rvm: ruby-head
18
+ gemfile: gemfiles/railsmaster.gemfile
19
+ allow_failures:
20
+ - rvm: ruby-head
21
+ gemfile: gemfiles/railsmaster.gemfile
data/Gemfile CHANGED
@@ -7,5 +7,5 @@ local_gemfile = 'Gemfile.local'
7
7
  if File.exist?(local_gemfile)
8
8
  eval(File.read(local_gemfile)) # rubocop:disable Lint/Eval
9
9
  else
10
- gem 'activerecord', '~>4.2'
10
+ gem 'activerecord', '5.1.0'
11
11
  end
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 **Rails** ~> 4.2.
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
- gem "store_attribute", "~>0.4.0" # version 0.4.x is for Rails 4.2.x and 0.5.x is for Rails 5
17
+ # for Rails 5+ (6 is supported)
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,14 +26,14 @@ 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
- .store_attribute(store_name, name, type, options = {})
29
+ store_attribute(store_name, name, type, options)
24
30
  ```
25
31
 
26
32
  Where:
27
33
  - `store_name` The name of the store.
28
34
  - `name` The name of the accessor to the store.
29
35
  - `type` A symbol such as `:string` or `:integer`, or a type object to be used for the accessor.
30
- - `options` A hash of cast type options such as `precision`, `limit`, `scale`.
36
+ - `options` (optional) A hash of cast type options such as `precision`, `limit`, `scale`.
31
37
 
32
38
  Type casting occurs every time you write data through accessor or update store itself
33
39
  and when object is loaded from database.
@@ -43,10 +49,10 @@ class MegaUser < User
43
49
  store_attribute :settings, :active, :boolean
44
50
  end
45
51
 
46
- u = MegaUser.new(active: false, login_at: '2015-01-01 00:01', ratio: "63.4608")
52
+ u = MegaUser.new(active: false, login_at: "2015-01-01 00:01", ratio: "63.4608")
47
53
 
48
54
  u.login_at.is_a?(DateTime) # => true
49
- u.login_at = DateTime.new(2015,1,1,11,0,0)
55
+ u.login_at = DateTime.new(2015, 1, 1, 11, 0, 0)
50
56
  u.ratio # => 63
51
57
  u.active # => false
52
58
  # And we also have a predicate method
@@ -54,17 +60,17 @@ u.active? # => false
54
60
  u.reload
55
61
 
56
62
  # After loading record from db store contains casted data
57
- u.settings['login_at'] == DateTime.new(2015,1,1,11,0,0) # => true
63
+ u.settings["login_at"] == DateTime.new(2015, 1, 1, 11, 0, 0) # => true
58
64
 
59
65
  # If you update store explicitly then the value returned
60
66
  # by accessor isn't type casted
61
- u.settings['ration'] = "3.141592653"
67
+ u.settings["ratio"] = "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.14.1592653"
71
+ u.ratio = "3.141592653"
66
72
  u.ratio # => 3
67
- u.settings['ratio'] # => 3
73
+ u.settings["ratio"] # => 3
68
74
  ```
69
75
 
70
76
  You can also specify type using usual `store_accessor` method:
@@ -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
+ ```
data/Rakefile CHANGED
@@ -1,6 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "bundler/gem_tasks"
4
+ require "rspec/core/rake_task"
5
+ require "rubocop/rake_task"
2
6
 
3
- require 'rspec/core/rake_task'
4
7
  RSpec::Core::RakeTask.new(:spec)
8
+ RuboCop::RakeTask.new
5
9
 
6
- task :default => :spec
10
+ task default: [:rubocop, :spec]
@@ -1,5 +1,5 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- gem 'activerecord', "~>4.2"
3
+ gem 'rails', '~> 5.1.0'
4
4
 
5
5
  gemspec path: '..'
@@ -0,0 +1,5 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'rails', '6.0.0.beta3'
4
+
5
+ gemspec path: '..'
@@ -1,7 +1,5 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- gem 'rack', github: "rack/rack"
4
- gem 'arel', github: 'rails/arel'
5
3
  gem 'rails', github: 'rails/rails'
6
4
 
7
5
  gemspec path: '..'
@@ -1,2 +1,4 @@
1
- require 'store_attribute/version'
2
- require 'store_attribute/active_record'
1
+ # frozen_string_literal: true
2
+
3
+ require "store_attribute/version"
4
+ require "store_attribute/active_record"
@@ -1 +1,3 @@
1
- require 'store_attribute/active_record/store'
1
+ # frozen_string_literal: true
2
+
3
+ require "store_attribute/active_record/store"
@@ -1,9 +1,12 @@
1
- require 'active_record/store'
2
- require 'store_attribute/active_record/type/typed_store'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_record/store"
4
+ require "store_attribute/active_record/type/typed_store"
3
5
 
4
6
  module ActiveRecord
5
7
  module Store
6
8
  module ClassMethods # :nodoc:
9
+ alias _orig_store store
7
10
  # Defines store on this model.
8
11
  #
9
12
  # +store_name+ The name of the store.
@@ -21,9 +24,11 @@ module ActiveRecord
21
24
  # store :settings, accessors: [:color, :homepage, login_at: :datetime], coder: JSON
22
25
  # end
23
26
  def store(store_name, options = {})
24
- serialize store_name, IndifferentCoder.new(options[:coder])
25
- store_accessor(store_name, *options[:accessors]) if options.key?(:accessors)
27
+ accessors = options.delete(:accessors)
28
+ _orig_store(store_name, options)
29
+ store_accessor(store_name, *accessors) if accessors
26
30
  end
31
+
27
32
  # Adds additional accessors to an existing store on this model.
28
33
  #
29
34
  # +store_name+ The name of the store.
@@ -1,22 +1,9 @@
1
- require 'active_record/type'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_record/type"
2
4
 
3
5
  module ActiveRecord
4
6
  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
7
  class TypedStore < DelegateClass(ActiveRecord::Type::Value) # :nodoc:
21
8
  # Creates +TypedStore+ type instance and specifies type caster
22
9
  # for key.
@@ -33,26 +20,26 @@ module ActiveRecord
33
20
  end
34
21
 
35
22
  def add_typed_key(key, type, **options)
36
- type = Type.lookup_type(type, options) if type.is_a?(Symbol)
23
+ type = ActiveRecord::Type.lookup(type, options) if type.is_a?(Symbol)
37
24
  @accessor_types[key.to_s] = type
38
25
  end
39
26
 
40
- def type_cast_from_database(value)
27
+ def deserialize(value)
41
28
  hash = super
42
29
  if hash
43
30
  accessor_types.each do |key, type|
44
- hash[key] = type.type_cast_from_database(hash[key]) if hash.key?(key)
31
+ hash[key] = type.deserialize(hash[key]) if hash.key?(key)
45
32
  end
46
33
  end
47
34
  hash
48
35
  end
49
36
 
50
- def type_cast_for_database(value)
37
+ def serialize(value)
51
38
  if value.is_a?(Hash)
52
39
  typed_casted = {}
53
40
  accessor_types.each do |key, type|
54
41
  k = key_to_cast(value, key)
55
- typed_casted[k] = type.type_cast_for_database(value[k]) unless k.nil?
42
+ typed_casted[k] = type.serialize(value[k]) unless k.nil?
56
43
  end
57
44
  super(value.merge(typed_casted))
58
45
  else
@@ -60,11 +47,11 @@ module ActiveRecord
60
47
  end
61
48
  end
62
49
 
63
- def type_cast_from_user(value)
50
+ def cast(value)
64
51
  hash = super
65
52
  if hash
66
53
  accessor_types.each do |key, type|
67
- hash[key] = type.type_cast_from_user(hash[key]) if hash.key?(key)
54
+ hash[key] = type.cast(hash[key]) if hash.key?(key)
68
55
  end
69
56
  end
70
57
  hash
@@ -75,7 +62,7 @@ module ActiveRecord
75
62
  end
76
63
 
77
64
  def write(object, attribute, key, value)
78
- value = type_for(key).type_cast_from_user(value) if typed?(key)
65
+ value = type_for(key).cast(value) if typed?(key)
79
66
  store_accessor.write(object, attribute, key, value)
80
67
  end
81
68
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module StoreAttribute # :nodoc:
2
- VERSION = "0.4.1".freeze
4
+ VERSION = "0.5.3"
3
5
  end
@@ -1,11 +1,13 @@
1
- require 'spec_helper'
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
2
4
 
3
5
  describe StoreAttribute do
4
6
  before do
5
7
  @connection = ActiveRecord::Base.connection
6
8
 
7
9
  @connection.transaction do
8
- @connection.create_table('users') do |t|
10
+ @connection.create_table("users") do |t|
9
11
  t.jsonb :jparams, default: {}, null: false
10
12
  t.text :custom
11
13
  t.hstore :hdata, default: {}, null: false
@@ -16,23 +18,23 @@ describe StoreAttribute do
16
18
  end
17
19
 
18
20
  after do
19
- @connection.drop_table 'users', if_exists: true
21
+ @connection.drop_table "users", if_exists: true
20
22
  end
21
23
 
22
24
  let(:time) { DateTime.new(2015, 2, 14, 17, 0, 0) }
23
- let(:time_str) { '2015-02-14 17:00' }
24
- let(:time_str_utc) { '2015-02-14 17:00:00 UTC' }
25
+ let(:time_str) { "2015-02-14 17:00" }
26
+ let(:time_str_utc) { "2015-02-14 17:00:00 UTC" }
25
27
 
26
28
  context "hstore" do
27
29
  it "typecasts on build" do
28
- user = User.new(visible: 't', login_at: time_str)
30
+ user = User.new(visible: "t", login_at: time_str)
29
31
  expect(user.visible).to eq true
30
32
  expect(user).to be_visible
31
33
  expect(user.login_at).to eq time
32
34
  end
33
35
 
34
36
  it "typecasts on reload" do
35
- user = User.new(visible: 't', login_at: time_str)
37
+ user = User.new(visible: "t", login_at: time_str)
36
38
  user.save!
37
39
  user = User.find(user.id)
38
40
 
@@ -54,8 +56,8 @@ describe StoreAttribute do
54
56
  expect(user.login_at).to eq time
55
57
 
56
58
  ron = RawUser.find(user.id)
57
- expect(ron.hdata['visible']).to eq 'false'
58
- expect(ron.hdata['login_at']).to eq time_str_utc
59
+ expect(ron.hdata["visible"]).to eq "false"
60
+ expect(ron.hdata["login_at"]).to eq time_str_utc
59
61
  end
60
62
 
61
63
  it "handles options" do
@@ -63,8 +65,8 @@ describe StoreAttribute do
63
65
  end
64
66
 
65
67
  it "YAML roundtrip" do
66
- user = User.create!(visible: '0', login_at: time_str)
67
- dumped = YAML.load(YAML.dump(user))
68
+ user = User.create!(visible: "0", login_at: time_str)
69
+ dumped = YAML.load(YAML.dump(user)) # rubocop:disable Security/YAMLLoad
68
70
 
69
71
  expect(dumped.visible).to be false
70
72
  expect(dumped.login_at).to eq time
@@ -74,26 +76,26 @@ describe StoreAttribute do
74
76
  context "jsonb" do
75
77
  it "typecasts on build" do
76
78
  jamie = User.new(
77
- active: 'true',
79
+ active: "true",
78
80
  salary: 3.1999,
79
- birthday: '2000-01-01'
81
+ birthday: "2000-01-01"
80
82
  )
81
83
  expect(jamie).to be_active
82
84
  expect(jamie.salary).to eq 3
83
85
  expect(jamie.birthday).to eq Date.new(2000, 1, 1)
84
- expect(jamie.jparams['birthday']).to eq Date.new(2000, 1, 1)
85
- expect(jamie.jparams['active']).to eq true
86
+ expect(jamie.jparams["birthday"]).to eq Date.new(2000, 1, 1)
87
+ expect(jamie.jparams["active"]).to eq true
86
88
  end
87
89
 
88
90
  it "typecasts on reload" do
89
- jamie = User.create!(jparams: { 'active' => '1', 'birthday' => '01/01/2000', 'salary' => '3.14' })
91
+ jamie = User.create!(jparams: {"active" => "1", "birthday" => "01/01/2000", "salary" => "3.14"})
90
92
  jamie = User.find(jamie.id)
91
93
 
92
94
  expect(jamie).to be_active
93
95
  expect(jamie.salary).to eq 3
94
96
  expect(jamie.birthday).to eq Date.new(2000, 1, 1)
95
- expect(jamie.jparams['birthday']).to eq Date.new(2000, 1, 1)
96
- expect(jamie.jparams['active']).to eq true
97
+ expect(jamie.jparams["birthday"]).to eq Date.new(2000, 1, 1)
98
+ expect(jamie.jparams["active"]).to eq true
97
99
  end
98
100
 
99
101
  it "works with accessors" do
@@ -101,9 +103,9 @@ describe StoreAttribute do
101
103
  john.active = 1
102
104
 
103
105
  expect(john).to be_active
104
- expect(john.jparams['active']).to eq true
106
+ expect(john.jparams["active"]).to eq true
105
107
 
106
- john.jparams = { active: 'true', salary: '123.123', birthday: '01/01/2012' }
108
+ john.jparams = {active: "true", salary: "123.123", birthday: "01/01/2012"}
107
109
  expect(john).to be_active
108
110
  expect(john.birthday).to eq Date.new(2012, 1, 1)
109
111
  expect(john.salary).to eq 123
@@ -111,9 +113,9 @@ describe StoreAttribute do
111
113
  john.save!
112
114
 
113
115
  ron = RawUser.find(john.id)
114
- expect(ron.jparams['active']).to eq true
115
- expect(ron.jparams['birthday']).to eq '2012-01-01'
116
- expect(ron.jparams['salary']).to eq 123
116
+ expect(ron.jparams["active"]).to eq true
117
+ expect(ron.jparams["birthday"]).to eq "2012-01-01"
118
+ expect(ron.jparams["salary"]).to eq 123
117
119
  end
118
120
 
119
121
  it "re-typecast old data" do
@@ -127,8 +129,8 @@ describe StoreAttribute do
127
129
  jamie.save!
128
130
 
129
131
  ron = RawUser.find(jamie.id)
130
- expect(ron.jparams['active']).to eq true
131
- expect(ron.jparams['salary']).to eq 12
132
+ expect(ron.jparams["active"]).to eq true
133
+ expect(ron.jparams["salary"]).to eq 12
132
134
  end
133
135
  end
134
136
 
@@ -139,7 +141,7 @@ describe StoreAttribute do
139
141
  end
140
142
 
141
143
  it "typecasts on reload" do
142
- jamie = User.create!(custom: { price: '$12' })
144
+ jamie = User.create!(custom: {price: "$12"})
143
145
  expect(jamie.reload.price).to eq 1200
144
146
 
145
147
  jamie = User.find(jamie.id)
@@ -150,22 +152,22 @@ describe StoreAttribute do
150
152
 
151
153
  context "store subtype" do
152
154
  it "typecasts on build" do
153
- user = User.new(inner_json: { x: 1 })
154
- expect(user.inner_json).to eq('x' => 1)
155
+ user = User.new(inner_json: {x: 1})
156
+ expect(user.inner_json).to eq("x" => 1)
155
157
  end
156
158
 
157
159
  it "typecasts on update" do
158
160
  user = User.new
159
- user.update!(inner_json: { x: 1 })
160
- expect(user.inner_json).to eq('x' => 1)
161
+ user.update!(inner_json: {x: 1})
162
+ expect(user.inner_json).to eq("x" => 1)
161
163
 
162
- expect(user.reload.inner_json).to eq('x' => 1)
164
+ expect(user.reload.inner_json).to eq("x" => 1)
163
165
  end
164
166
 
165
167
  it "typecasts on reload" do
166
- jamie = User.create!(inner_json: { x: 1 })
168
+ jamie = User.create!(inner_json: {x: 1})
167
169
  jamie = User.find(jamie.id)
168
- expect(jamie.inner_json).to eq('x' => 1)
170
+ expect(jamie.inner_json).to eq("x" => 1)
169
171
  end
170
172
  end
171
173
  end
data/spec/spec_helper.rb CHANGED
@@ -1,26 +1,30 @@
1
- $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
1
+ # frozen_string_literal: true
2
+
3
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), "..", "lib"))
2
4
  $LOAD_PATH.unshift(File.dirname(__FILE__))
3
5
 
4
- if ENV['COVER']
5
- require 'simplecov'
6
- SimpleCov.root File.join(File.dirname(__FILE__), '..')
6
+ if ENV["COVER"]
7
+ require "simplecov"
8
+ SimpleCov.root File.join(File.dirname(__FILE__), "..")
7
9
  SimpleCov.start
8
10
  end
9
11
 
10
- require 'rspec'
11
- require 'pry-byebug'
12
- require 'active_record'
13
- require 'pg'
14
- require 'store_attribute'
12
+ require "rspec"
13
+ require "pry-byebug"
14
+ require "active_record"
15
+ require "pg"
16
+ require "store_attribute"
17
+
18
+ RAILS_5_1 = ActiveRecord.version.release >= Gem::Version.new("5.1.0")
15
19
 
16
20
  ActiveRecord::Base.establish_connection(
17
- adapter: 'postgresql',
18
- database: 'store_attribute_test'
21
+ adapter: "postgresql",
22
+ database: "store_attribute_test"
19
23
  )
20
24
  connection = ActiveRecord::Base.connection
21
25
 
22
- unless connection.extension_enabled?('hstore')
23
- connection.enable_extension 'hstore'
26
+ unless connection.extension_enabled?("hstore")
27
+ connection.enable_extension "hstore"
24
28
  connection.commit_db_transaction
25
29
  end
26
30
 
@@ -31,12 +35,11 @@ Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
31
35
  RSpec.configure do |config|
32
36
  config.mock_with :rspec
33
37
 
34
- config.filter_run :focus
35
- config.run_all_when_everything_filtered = true
38
+ config.filter_run_when_matching :focus
36
39
 
37
40
  config.example_status_persistence_file_path = "tmp/rspec_examples.txt"
38
41
 
39
42
  if config.files_to_run.one?
40
- config.default_formatter = 'doc'
43
+ config.default_formatter = "doc"
41
44
  end
42
45
  end
@@ -1,94 +1,109 @@
1
- require 'spec_helper'
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
2
4
 
3
5
  describe ActiveRecord::Type::TypedStore do
4
6
  let(:json_type) { ActiveRecord::Type::Serialized.new(ActiveRecord::Type::Text.new, ActiveRecord::Coders::JSON) }
5
- let(:yaml_type) do
6
- ActiveRecord::Type::Serialized.new(
7
- ActiveRecord::Type::Text.new,
8
- ActiveRecord::Store::IndifferentCoder.new(
9
- ActiveRecord::Coders::YAMLColumn.new(Hash)
10
- )
11
- )
12
- end
13
7
 
14
8
  context "with json store" do
15
9
  subject { described_class.new(json_type) }
16
10
 
17
- describe "#type_cast_from_user" do
11
+ describe "#cast" do
18
12
  it "without key types", :aggregate_failures do
19
- expect(subject.type_cast_from_user([1, 2])).to eq [1, 2]
20
- expect(subject.type_cast_from_user('a' => 'b')).to eq('a' => 'b')
13
+ expect(subject.cast([1, 2])).to eq [1, 2]
14
+ expect(subject.cast("a" => "b")).to eq("a" => "b")
21
15
  end
22
16
 
23
17
  it "with type keys" do
24
- subject.add_typed_key('date', :date)
18
+ subject.add_typed_key("date", :date)
25
19
 
26
20
  date = ::Date.new(2016, 6, 22)
27
- expect(subject.type_cast_from_user(date: '2016-06-22')).to eq('date' => date)
21
+ expect(subject.cast(date: "2016-06-22")).to eq("date" => date)
28
22
  end
29
23
  end
30
24
 
31
- describe "#type_cast_from_database" do
25
+ describe "#deserialize" do
32
26
  it "without key types", :aggregate_failures do
33
- expect(subject.type_cast_from_database('[1,2]')).to eq [1, 2]
34
- expect(subject.type_cast_from_database('{"a":"b"}')).to eq('a' => 'b')
27
+ expect(subject.deserialize("[1,2]")).to eq [1, 2]
28
+ expect(subject.deserialize('{"a":"b"}')).to eq("a" => "b")
35
29
  end
36
30
 
37
31
  it "with type keys" do
38
- subject.add_typed_key('date', :date)
32
+ subject.add_typed_key("date", :date)
39
33
 
40
34
  date = ::Date.new(2016, 6, 22)
41
- expect(subject.type_cast_from_database('{"date":"2016-06-22"}')).to eq('date' => date)
35
+ expect(subject.deserialize('{"date":"2016-06-22"}')).to eq("date" => date)
42
36
  end
43
37
  end
44
38
 
45
- describe "#type_cast_for_database" do
39
+ describe "#serialize" do
46
40
  it "without key types", :aggregate_failures do
47
- expect(subject.type_cast_for_database([1, 2])).to eq '[1,2]'
48
- expect(subject.type_cast_for_database('a' => 'b')).to eq '{"a":"b"}'
41
+ expect(subject.serialize([1, 2])).to eq "[1,2]"
42
+ expect(subject.serialize("a" => "b")).to eq '{"a":"b"}'
49
43
  end
50
44
 
51
45
  it "with type keys" do
52
- subject.add_typed_key('date', :date)
46
+ subject.add_typed_key("date", :date)
53
47
 
54
48
  date = ::Date.new(2016, 6, 22)
55
- expect(subject.type_cast_for_database(date: date)).to eq '{"date":"2016-06-22"}'
49
+ expect(subject.serialize(date: date)).to eq '{"date":"2016-06-22"}'
56
50
  end
57
51
 
58
52
  it "with type key with option" do
59
- subject.add_typed_key('val', :integer, limit: 1)
53
+ subject.add_typed_key("val", :integer, limit: 1)
60
54
 
61
- expect { subject.type_cast_for_database(val: 1024) }.to raise_error(RangeError)
55
+ expect { subject.serialize(val: 1024) }.to raise_error(RangeError)
62
56
  end
63
57
  end
64
58
 
65
59
  describe ".create_from_type" do
66
60
  it "creates with valid types", :aggregate_failures do
67
- type = described_class.create_from_type(json_type, 'date', :date)
68
- new_type = described_class.create_from_type(type, 'val', :integer)
61
+ type = described_class.create_from_type(json_type, "date", :date)
62
+ new_type = described_class.create_from_type(type, "val", :integer)
69
63
 
70
64
  date = ::Date.new(2016, 6, 22)
71
65
 
72
- expect(type.type_cast_from_user(date: '2016-06-22', val: '1.2')).to eq('date' => date, 'val' => '1.2')
73
- expect(new_type.type_cast_from_user(date: '2016-06-22', val: '1.2')).to eq('date' => date, 'val' => 1)
66
+ expect(type.cast(date: "2016-06-22", val: "1.2")).to eq("date" => date, "val" => "1.2")
67
+ expect(new_type.cast(date: "2016-06-22", val: "1.2")).to eq("date" => date, "val" => 1)
74
68
  end
75
69
  end
76
70
  end
77
71
 
78
72
  context "with yaml coder" do
73
+ if RAILS_5_1
74
+ let(:yaml_type) do
75
+ ActiveRecord::Type::Serialized.new(
76
+ ActiveRecord::Type::Text.new,
77
+ ActiveRecord::Store::IndifferentCoder.new(
78
+ "test",
79
+ ActiveRecord::Coders::YAMLColumn.new("test", Hash)
80
+ )
81
+ )
82
+ end
83
+ else
84
+ let(:yaml_type) do
85
+ ActiveRecord::Type::Serialized.new(
86
+ ActiveRecord::Type::Text.new,
87
+ ActiveRecord::Store::IndifferentCoder.new(
88
+ ActiveRecord::Coders::YAMLColumn.new(Hash)
89
+ )
90
+ )
91
+ end
92
+ end
93
+
79
94
  let(:subject) { described_class.new(yaml_type) }
80
95
 
81
96
  it "works", :aggregate_failures do
82
- subject.add_typed_key('date', :date)
97
+ subject.add_typed_key("date", :date)
83
98
 
84
99
  date = ::Date.new(2016, 6, 22)
85
100
 
86
- expect(subject.type_cast_from_user(date: '2016-06-22')).to eq('date' => date)
87
- expect(subject.type_cast_from_user('date' => '2016-06-22')).to eq('date' => date)
88
- expect(subject.type_cast_from_database("---\n:date: 2016-06-22\n")).to eq('date' => date)
89
- expect(subject.type_cast_from_database("---\ndate: 2016-06-22\n")).to eq('date' => date)
90
- expect(subject.type_cast_for_database(date: date)).to eq "--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess\ndate: 2016-06-22\n"
91
- expect(subject.type_cast_for_database('date' => date)).to eq "--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess\ndate: 2016-06-22\n"
101
+ expect(subject.cast(date: "2016-06-22")).to eq("date" => date)
102
+ expect(subject.cast("date" => "2016-06-22")).to eq("date" => date)
103
+ expect(subject.deserialize("---\n:date: 2016-06-22\n")).to eq("date" => date)
104
+ expect(subject.deserialize("---\ndate: 2016-06-22\n")).to eq("date" => date)
105
+ expect(subject.serialize(date: date)).to eq "--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess\ndate: 2016-06-22\n"
106
+ expect(subject.serialize("date" => date)).to eq "--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess\ndate: 2016-06-22\n"
92
107
  end
93
108
  end
94
109
  end
@@ -1,7 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class MoneyType < ActiveRecord::Type::Integer
2
- def type_cast_from_user(value)
3
- if !value.is_a?(Numeric) && value.include?('$')
4
- price_in_dollars = value.delete('$').to_f
4
+ def cast(value)
5
+ if !value.is_a?(Numeric) && value.include?("$")
6
+ price_in_dollars = value.delete("$").to_f
5
7
  super(price_in_dollars * 100)
6
8
  else
7
9
  super
@@ -9,4 +11,4 @@ class MoneyType < ActiveRecord::Type::Integer
9
11
  end
10
12
  end
11
13
 
12
- ActiveRecord::Base.connection.type_map.register_type('money_type', MoneyType.new)
14
+ ActiveRecord::Type.register(:money_type, MoneyType)
data/spec/support/user.rb CHANGED
@@ -1,5 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class RawUser < ActiveRecord::Base
2
- self.table_name = 'users'
4
+ self.table_name = "users"
3
5
  end
4
6
 
5
7
  class User < ActiveRecord::Base
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  $:.push File.expand_path("../lib", __FILE__)
2
4
 
3
5
  # Maintain your gem's version:
@@ -17,11 +19,16 @@ Gem::Specification.new do |s|
17
19
  s.files = `git ls-files`.split($/)
18
20
  s.require_paths = ["lib"]
19
21
 
20
- s.add_runtime_dependency "activerecord", ">=4.2.0"
22
+ s.required_ruby_version = ">= 2.4.0"
23
+
24
+ s.add_runtime_dependency "activerecord", ">= 5.0"
21
25
 
22
- s.add_development_dependency "pg", "~>0.18"
23
- s.add_development_dependency "rake", "~> 10.1"
26
+ s.add_development_dependency "pg", ">= 0.18"
27
+ s.add_development_dependency "rake", ">= 10.1"
24
28
  s.add_development_dependency "simplecov", ">= 0.3.8"
25
29
  s.add_development_dependency "pry-byebug"
26
- s.add_development_dependency "rspec", "~> 3.4.0"
30
+ s.add_development_dependency "rubocop", "~> 0.65.0"
31
+ s.add_development_dependency "rubocop-md", "~> 0.2"
32
+ s.add_development_dependency "standard", "~> 0.0.36"
33
+ s.add_development_dependency "rspec", ">= 3.5.0"
27
34
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: store_attribute
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.1
4
+ version: 0.5.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - palkan
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-07-08 00:00:00.000000000 Z
11
+ date: 2019-04-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -16,40 +16,40 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 4.2.0
19
+ version: '5.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: 4.2.0
26
+ version: '5.0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: pg
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - "~>"
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
33
  version: '0.18'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - "~>"
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0.18'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rake
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - "~>"
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
47
  version: '10.1'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - "~>"
52
+ - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '10.1'
55
55
  - !ruby/object:Gem::Dependency
@@ -81,19 +81,61 @@ dependencies:
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
83
  - !ruby/object:Gem::Dependency
84
- name: rspec
84
+ name: rubocop
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: 0.65.0
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: 0.65.0
97
+ - !ruby/object:Gem::Dependency
98
+ name: rubocop-md
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '0.2'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '0.2'
111
+ - !ruby/object:Gem::Dependency
112
+ name: standard
85
113
  requirement: !ruby/object:Gem::Requirement
86
114
  requirements:
87
115
  - - "~>"
88
116
  - !ruby/object:Gem::Version
89
- version: 3.4.0
117
+ version: 0.0.36
90
118
  type: :development
91
119
  prerelease: false
92
120
  version_requirements: !ruby/object:Gem::Requirement
93
121
  requirements:
94
122
  - - "~>"
95
123
  - !ruby/object:Gem::Version
96
- version: 3.4.0
124
+ version: 0.0.36
125
+ - !ruby/object:Gem::Dependency
126
+ name: rspec
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: 3.5.0
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: 3.5.0
97
139
  description: ActiveRecord extension which adds typecasting to store accessors
98
140
  email:
99
141
  - dementiev.vm@gmail.com
@@ -113,8 +155,9 @@ files:
113
155
  - bench/setup.rb
114
156
  - bin/console
115
157
  - bin/setup
116
- - gemfiles/rails-edge.gemfile
117
- - gemfiles/rails42.gemfile
158
+ - gemfiles/rails5.gemfile
159
+ - gemfiles/rails6.gemfile
160
+ - gemfiles/railsmaster.gemfile
118
161
  - lib/store_attribute.rb
119
162
  - lib/store_attribute/active_record.rb
120
163
  - lib/store_attribute/active_record/store.rb
@@ -138,15 +181,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
138
181
  requirements:
139
182
  - - ">="
140
183
  - !ruby/object:Gem::Version
141
- version: '0'
184
+ version: 2.4.0
142
185
  required_rubygems_version: !ruby/object:Gem::Requirement
143
186
  requirements:
144
187
  - - ">="
145
188
  - !ruby/object:Gem::Version
146
189
  version: '0'
147
190
  requirements: []
148
- rubyforge_project:
149
- rubygems_version: 2.6.4
191
+ rubygems_version: 3.0.2
150
192
  signing_key:
151
193
  specification_version: 4
152
194
  summary: ActiveRecord extension which adds typecasting to store accessors