modis 2.1.0 → 4.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.gitignore +1 -1
- data/.rubocop.yml +1 -0
- data/.ruby-version +1 -1
- data/.travis.yml +37 -7
- data/Appraisals +26 -0
- data/CHANGELOG.md +38 -0
- data/Gemfile +0 -14
- data/Gemfile.lock +96 -0
- data/README.md +22 -14
- data/benchmark/persistence.rb +1 -1
- data/gemfiles/rails_5.2.gemfile +8 -0
- data/gemfiles/rails_6.0.gemfile +8 -0
- data/gemfiles/rails_6.1.gemfile +8 -0
- data/lib/modis.rb +23 -14
- data/lib/modis/attribute.rb +8 -8
- data/lib/modis/finder.rb +3 -3
- data/lib/modis/index.rb +3 -0
- data/lib/modis/model.rb +2 -1
- data/lib/modis/persistence.rb +22 -15
- data/lib/modis/version.rb +1 -1
- data/modis.gemspec +14 -4
- data/spec/persistence_spec.rb +56 -0
- data/spec/spec_helper.rb +1 -1
- data/spec/support/simplecov_helper.rb +1 -3
- metadata +123 -21
- data/.ruby-gemset +0 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 62a6abe9671e399409e452a290c360fcd0aadfbdceccca9aa364d6f232b2df49
|
4
|
+
data.tar.gz: d8468a3f54bf0587f8d89ff2b353a5c48ea0798a4c067bd291ef5ed471448a01
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a382d676431ed8bd7fd79dde5dbff275c19687b42ce9de52980ce35898ea91eb447a1a7349b8f09bc56606841e7f6cada8f882bc23f5eb8d9f5483b109805d61
|
7
|
+
data.tar.gz: 499687970a4a33a573e16ea8f1b70749e85d2650b2092a37ce26cdd9452cc6c3a3c539e9e59dcfa9d5db0ed2d9ccf19c961122e22d0e8dfd3e41afda080c925d
|
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.
|
1
|
+
2.6.5
|
data/.travis.yml
CHANGED
@@ -1,12 +1,42 @@
|
|
1
|
-
sudo: false
|
2
|
-
services:
|
3
|
-
- redis-server
|
4
1
|
language: ruby
|
2
|
+
|
3
|
+
dist: bionic
|
4
|
+
|
5
|
+
cache: bundler
|
6
|
+
|
7
|
+
services:
|
8
|
+
- redis-server
|
9
|
+
|
5
10
|
rvm:
|
6
|
-
- 2.
|
7
|
-
- 2.
|
8
|
-
- 2.
|
9
|
-
-
|
11
|
+
- 2.3
|
12
|
+
- 2.4
|
13
|
+
- 2.5
|
14
|
+
- 2.6
|
15
|
+
- 2.7
|
16
|
+
- 3.0
|
17
|
+
- jruby-9.2.17.0
|
18
|
+
|
19
|
+
gemfile:
|
20
|
+
- gemfiles/rails_5.2.gemfile
|
21
|
+
- gemfiles/rails_6.0.gemfile
|
22
|
+
- gemfiles/rails_6.1.gemfile
|
23
|
+
|
24
|
+
matrix:
|
25
|
+
fast_finish: true
|
26
|
+
exclude:
|
27
|
+
# Rails 6 requires Ruby 2.5 or higher
|
28
|
+
- gemfile: gemfiles/rails_6.0.gemfile
|
29
|
+
rvm: 2.3
|
30
|
+
- gemfile: gemfiles/rails_6.1.gemfile
|
31
|
+
rvm: 2.3
|
32
|
+
- gemfile: gemfiles/rails_6.0.gemfile
|
33
|
+
rvm: 2.4
|
34
|
+
- gemfile: gemfiles/rails_6.1.gemfile
|
35
|
+
rvm: 2.4
|
36
|
+
# Rails 5.2 isn't compatible with Ruby 3.0 or higher
|
37
|
+
- gemfile: gemfiles/rails_5.2.gemfile
|
38
|
+
rvm: 3.0
|
39
|
+
|
10
40
|
env:
|
11
41
|
global:
|
12
42
|
secure: LrTz0Pq2ibNZuKDhdzcrvEUSNxUpPopEq9aJeCxy3UpV0v4vpHBtWV0S6zofvf98g/RkZ6cGI1u+0H578dHgE6pWTo+iR8LAwqPKofrFIWRkeo+M77Vs5swahb3mQyPOcig1hfVWDm25MsojePYm70eBIcBU55NWImtdePXfiU0=
|
data/Appraisals
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
appraise 'rails-4.2' do
|
4
|
+
gem 'activemodel', '~> 4.2.0'
|
5
|
+
gem 'activesupport', '~> 4.2.0'
|
6
|
+
end
|
7
|
+
|
8
|
+
appraise 'rails-5.0' do
|
9
|
+
gem 'activemodel', '~> 5.0.0'
|
10
|
+
gem 'activesupport', '~> 5.0.0'
|
11
|
+
end
|
12
|
+
|
13
|
+
appraise 'rails-5.1' do
|
14
|
+
gem 'activemodel', '~> 5.1.0'
|
15
|
+
gem 'activesupport', '~> 5.1.0'
|
16
|
+
end
|
17
|
+
|
18
|
+
appraise 'rails-5.2' do
|
19
|
+
gem 'activemodel', '~> 5.2.0'
|
20
|
+
gem 'activesupport', '~> 5.2.0'
|
21
|
+
end
|
22
|
+
|
23
|
+
appraise 'rails-6.0' do
|
24
|
+
gem 'activemodel', '~> 6.0.0'
|
25
|
+
gem 'activesupport', '~> 6.0.0'
|
26
|
+
end
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
## Unreleased
|
2
|
+
|
3
|
+
## v4.0.0 - 2021-04-28
|
4
|
+
|
5
|
+
**Breaking:**
|
6
|
+
|
7
|
+
- Drop support for Rails 4.2, 5.0, 5.1.
|
8
|
+
- Removed `hiredis` as a dependency and made it a development dependency.
|
9
|
+
For details, see [#31](https://github.com/rpush/modis/pull/31) by [@fdoxyz](https://github.com/fdoxyz).
|
10
|
+
|
11
|
+
## v3.3.0 - 2020-07-07
|
12
|
+
|
13
|
+
- Fix deprecation warnings when using Ruby >= 2.7, `activemodel` >= 6.0.3, or `redis` >= 4.2.0. [#30](https://github.com/rpush/modis/pull/30) by [@rofreg](https://github.com/rofreg).
|
14
|
+
|
15
|
+
## v3.2.0 - 2019-12-12
|
16
|
+
|
17
|
+
- Add missing `#update` and `#update!`. [#27](https://github.com/rpush/modis/pull/27) by [@dsantosmerino](https://github.com/dsantosmerino).
|
18
|
+
|
19
|
+
## v3.1.0 - 2019-10-18
|
20
|
+
|
21
|
+
- Test with Rails 6
|
22
|
+
- Drop i18n dependency (credit goes to [@jas14](https://github.com/jas14) in [#23](https://github.com/rpush/modis/pull/23))
|
23
|
+
|
24
|
+
## v3.0.0 - 2018-12-20
|
25
|
+
|
26
|
+
- Drop support for any Ruby < 2.3 and Rails < 4.2.
|
27
|
+
- Add support for Rails 5.2
|
28
|
+
- Resolve Rubocop lint violations
|
29
|
+
- Test combinations of Ruby and Rails versions in CI
|
30
|
+
|
31
|
+
## v2.1.0
|
32
|
+
|
33
|
+
- Add `enable_all_index` option to allow disabling the `all` keys. [#7](https://github.com/rpush/modis/pull/7)
|
34
|
+
|
35
|
+
## v2.0.0
|
36
|
+
|
37
|
+
- Support MRI 2.2.2+ and JRuby 9k+ [#5](https://github.com/rpush/modis/pull/5)
|
38
|
+
- Remove YAML (de)serialization support [#5](https://github.com/rpush/modis/pull/5)
|
data/Gemfile
CHANGED
@@ -2,18 +2,4 @@
|
|
2
2
|
|
3
3
|
source 'https://rubygems.org'
|
4
4
|
|
5
|
-
gem 'rake'
|
6
|
-
gem 'rspec'
|
7
|
-
|
8
|
-
platform :mri do
|
9
|
-
gem 'cane'
|
10
|
-
gem 'codeclimate-test-reporter', require: nil
|
11
|
-
gem 'rubocop', require: false
|
12
|
-
gem 'simplecov', require: false
|
13
|
-
end
|
14
|
-
|
15
|
-
platform :mri_21 do
|
16
|
-
gem 'stackprof'
|
17
|
-
end
|
18
|
-
|
19
5
|
gemspec
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
modis (4.0.0)
|
5
|
+
activemodel (>= 5.2)
|
6
|
+
activesupport (>= 5.2)
|
7
|
+
connection_pool (>= 2)
|
8
|
+
msgpack (>= 0.5)
|
9
|
+
redis (>= 3.0)
|
10
|
+
|
11
|
+
GEM
|
12
|
+
remote: https://rubygems.org/
|
13
|
+
specs:
|
14
|
+
activemodel (6.0.3.4)
|
15
|
+
activesupport (= 6.0.3.4)
|
16
|
+
activesupport (6.0.3.4)
|
17
|
+
concurrent-ruby (~> 1.0, >= 1.0.2)
|
18
|
+
i18n (>= 0.7, < 2)
|
19
|
+
minitest (~> 5.1)
|
20
|
+
tzinfo (~> 1.1)
|
21
|
+
zeitwerk (~> 2.2, >= 2.2.2)
|
22
|
+
appraisal (2.3.0)
|
23
|
+
bundler
|
24
|
+
rake
|
25
|
+
thor (>= 0.14.0)
|
26
|
+
ast (2.4.1)
|
27
|
+
cane (3.0.0)
|
28
|
+
parallel
|
29
|
+
codeclimate-test-reporter (1.0.7)
|
30
|
+
simplecov
|
31
|
+
concurrent-ruby (1.1.7)
|
32
|
+
connection_pool (2.2.3)
|
33
|
+
diff-lcs (1.4.4)
|
34
|
+
docile (1.3.2)
|
35
|
+
hiredis (0.6.3)
|
36
|
+
i18n (1.8.5)
|
37
|
+
concurrent-ruby (~> 1.0)
|
38
|
+
jaro_winkler (1.5.4)
|
39
|
+
minitest (5.14.2)
|
40
|
+
msgpack (1.3.3)
|
41
|
+
parallel (1.19.2)
|
42
|
+
parser (2.7.1.4)
|
43
|
+
ast (~> 2.4.1)
|
44
|
+
powerpack (0.1.2)
|
45
|
+
rainbow (3.0.0)
|
46
|
+
rake (13.0.1)
|
47
|
+
redis (4.2.1)
|
48
|
+
rspec (3.9.0)
|
49
|
+
rspec-core (~> 3.9.0)
|
50
|
+
rspec-expectations (~> 3.9.0)
|
51
|
+
rspec-mocks (~> 3.9.0)
|
52
|
+
rspec-core (3.9.2)
|
53
|
+
rspec-support (~> 3.9.3)
|
54
|
+
rspec-expectations (3.9.2)
|
55
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
56
|
+
rspec-support (~> 3.9.0)
|
57
|
+
rspec-mocks (3.9.1)
|
58
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
59
|
+
rspec-support (~> 3.9.0)
|
60
|
+
rspec-support (3.9.3)
|
61
|
+
rubocop (0.61.1)
|
62
|
+
jaro_winkler (~> 1.5.1)
|
63
|
+
parallel (~> 1.10)
|
64
|
+
parser (>= 2.5, != 2.5.1.1)
|
65
|
+
powerpack (~> 0.1)
|
66
|
+
rainbow (>= 2.2.2, < 4.0)
|
67
|
+
ruby-progressbar (~> 1.7)
|
68
|
+
unicode-display_width (~> 1.4.0)
|
69
|
+
ruby-progressbar (1.10.1)
|
70
|
+
simplecov (0.18.5)
|
71
|
+
docile (~> 1.1)
|
72
|
+
simplecov-html (~> 0.11)
|
73
|
+
simplecov-html (0.12.2)
|
74
|
+
thor (1.0.1)
|
75
|
+
thread_safe (0.3.6)
|
76
|
+
tzinfo (1.2.7)
|
77
|
+
thread_safe (~> 0.1)
|
78
|
+
unicode-display_width (1.4.1)
|
79
|
+
zeitwerk (2.4.0)
|
80
|
+
|
81
|
+
PLATFORMS
|
82
|
+
ruby
|
83
|
+
|
84
|
+
DEPENDENCIES
|
85
|
+
appraisal
|
86
|
+
cane
|
87
|
+
codeclimate-test-reporter
|
88
|
+
hiredis (>= 0.5)
|
89
|
+
modis!
|
90
|
+
rake
|
91
|
+
rspec
|
92
|
+
rubocop (= 0.61.1)
|
93
|
+
simplecov
|
94
|
+
|
95
|
+
BUNDLED WITH
|
96
|
+
2.1.4
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
[![Build Status](https://
|
1
|
+
[![Build Status](https://travis-ci.org/rpush/modis.svg?branch=master)](https://travis-ci.org/rpush/modis)
|
2
2
|
[![Code Climate](https://codeclimate.com/github/ileitch/modis/badges/gpa.svg)](https://codeclimate.com/github/ileitch/modis)
|
3
3
|
[![Test Coverage](https://codeclimate.com/github/ileitch/modis/badges/coverage.svg)](https://codeclimate.com/github/ileitch/modis)
|
4
4
|
|
@@ -8,32 +8,40 @@ ActiveModel + Redis with the aim to mimic ActiveRecord where possible.
|
|
8
8
|
|
9
9
|
## Requirements
|
10
10
|
|
11
|
-
Modis supports
|
11
|
+
Modis 4.0+ supports Rails 5.2 and higher, including Rails 6.1, as well as Ruby 2.3 and above, including Ruby 3.0. Tests are also being run with JRuby. For details please check the current CI setup.
|
12
|
+
|
13
|
+
For releases supporting older Rails versions such as 4.2-5.1 please check out the 3.x releases.
|
12
14
|
|
13
15
|
## Installation
|
14
16
|
|
15
17
|
Add this line to your application's Gemfile:
|
16
18
|
|
17
|
-
|
19
|
+
```ruby
|
20
|
+
gem 'modis'
|
21
|
+
```
|
18
22
|
|
19
23
|
And then execute:
|
20
24
|
|
21
|
-
|
25
|
+
```console
|
26
|
+
$ bundle
|
27
|
+
```
|
22
28
|
|
23
29
|
Or install it yourself as:
|
24
30
|
|
25
|
-
|
31
|
+
```console
|
32
|
+
$ gem install modis
|
33
|
+
```
|
26
34
|
|
27
35
|
## Usage
|
28
36
|
|
29
37
|
```ruby
|
30
38
|
class MyModel
|
31
|
-
include Modis::
|
32
|
-
attribute :name,
|
33
|
-
attribute :age,
|
39
|
+
include Modis::Model
|
40
|
+
attribute :name, :string
|
41
|
+
attribute :age, :integer
|
34
42
|
end
|
35
43
|
|
36
|
-
MyModel.create!(:
|
44
|
+
MyModel.create!(name: 'Ian', age: 28)
|
37
45
|
```
|
38
46
|
|
39
47
|
### all index
|
@@ -41,13 +49,13 @@ MyModel.create!(:name => 'Ian', :age => 28)
|
|
41
49
|
Modis, by default, creates an `all` index in redis in which it stores all the IDs for records created. As a result, a large amount of memory will be consumed if many ids are stored. The `all` index functionality can be turned off by using `enable_all_index`
|
42
50
|
|
43
51
|
```ruby
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
52
|
+
class MyModel
|
53
|
+
include Modis::Model
|
54
|
+
enable_all_index false
|
55
|
+
end
|
48
56
|
```
|
49
57
|
|
50
|
-
By disabling the `all` index functionality, the IDs of each record created won't be saved. As a side effect, using `all` finder method will raise a `IndexError` exception as we would not have enough information to fetch all records. See https://github.com/
|
58
|
+
By disabling the `all` index functionality, the IDs of each record created won't be saved. As a side effect, using `all` finder method will raise a `IndexError` exception as we would not have enough information to fetch all records. See https://github.com/rpush/modis/pull/7 for more context.
|
51
59
|
|
52
60
|
## Supported Features
|
53
61
|
|
data/benchmark/persistence.rb
CHANGED
data/lib/modis.rb
CHANGED
@@ -20,23 +20,32 @@ module Modis
|
|
20
20
|
@mutex = Mutex.new
|
21
21
|
|
22
22
|
class << self
|
23
|
-
|
24
|
-
|
25
|
-
end
|
23
|
+
attr_writer :redis_options, :connection_pool_size, :connection_pool_timeout,
|
24
|
+
:connection_pool
|
26
25
|
|
27
|
-
|
28
|
-
|
29
|
-
|
26
|
+
def redis_options
|
27
|
+
@redis_options ||= {}
|
28
|
+
end
|
30
29
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
30
|
+
def connection_pool_size
|
31
|
+
@connection_pool_size ||= 5
|
32
|
+
end
|
33
|
+
|
34
|
+
def connection_pool_timeout
|
35
|
+
@connection_pool_timeout ||= 5
|
36
36
|
end
|
37
|
-
end
|
38
37
|
|
39
|
-
|
40
|
-
|
38
|
+
def connection_pool
|
39
|
+
return @connection_pool if @connection_pool
|
40
|
+
|
41
|
+
@mutex.synchronize do
|
42
|
+
options = { size: connection_pool_size, timeout: connection_pool_timeout }
|
43
|
+
@connection_pool = ConnectionPool.new(options) { Redis.new(redis_options) }
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def with_connection
|
48
|
+
connection_pool.with { |connection| yield(connection) }
|
49
|
+
end
|
41
50
|
end
|
42
51
|
end
|
data/lib/modis/attribute.rb
CHANGED
@@ -19,8 +19,6 @@ module Modis
|
|
19
19
|
|
20
20
|
module ClassMethods
|
21
21
|
def bootstrap_attributes(parent = nil)
|
22
|
-
attr_reader :attributes
|
23
|
-
|
24
22
|
class << self
|
25
23
|
attr_accessor :attributes, :attributes_with_defaults
|
26
24
|
end
|
@@ -37,6 +35,7 @@ module Modis
|
|
37
35
|
|
38
36
|
type_classes = Array(type).map do |t|
|
39
37
|
raise UnsupportedAttributeType, t unless TYPES.key?(t)
|
38
|
+
|
40
39
|
TYPES[t]
|
41
40
|
end.flatten
|
42
41
|
|
@@ -53,7 +52,7 @@ module Modis
|
|
53
52
|
end
|
54
53
|
RUBY
|
55
54
|
|
56
|
-
class_eval <<-RUBY, __FILE__, __LINE__
|
55
|
+
class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
57
56
|
def #{name}
|
58
57
|
attributes['#{name}']
|
59
58
|
end
|
@@ -72,6 +71,10 @@ module Modis
|
|
72
71
|
end
|
73
72
|
end
|
74
73
|
|
74
|
+
def attributes
|
75
|
+
@modis_attributes
|
76
|
+
end
|
77
|
+
|
75
78
|
def assign_attributes(hash)
|
76
79
|
hash.each do |k, v|
|
77
80
|
setter = "#{k}="
|
@@ -91,15 +94,12 @@ module Modis
|
|
91
94
|
|
92
95
|
def set_sti_type
|
93
96
|
return unless self.class.sti_child?
|
94
|
-
write_attribute(:type, self.class.name)
|
95
|
-
end
|
96
97
|
|
97
|
-
|
98
|
-
@changed_attributes = nil
|
98
|
+
write_attribute(:type, self.class.name)
|
99
99
|
end
|
100
100
|
|
101
101
|
def apply_defaults
|
102
|
-
@
|
102
|
+
@modis_attributes = Hash[self.class.attributes_with_defaults]
|
103
103
|
end
|
104
104
|
end
|
105
105
|
end
|
data/lib/modis/finder.rb
CHANGED
@@ -33,9 +33,7 @@ module Modis
|
|
33
33
|
|
34
34
|
attributes = deserialize(record_for(redis, id))
|
35
35
|
|
36
|
-
unless attributes['id'].present?
|
37
|
-
raise RecordNotFound, "Couldn't find #{name} with id=#{id}"
|
38
|
-
end
|
36
|
+
raise RecordNotFound, "Couldn't find #{name} with id=#{id}" unless attributes['id'].present?
|
39
37
|
|
40
38
|
attributes
|
41
39
|
end
|
@@ -69,6 +67,7 @@ module Modis
|
|
69
67
|
def model_for(attributes)
|
70
68
|
cls = model_class(attributes)
|
71
69
|
return unless cls == self || cls < self
|
70
|
+
|
72
71
|
cls.new(attributes, new_record: false)
|
73
72
|
end
|
74
73
|
|
@@ -79,6 +78,7 @@ module Modis
|
|
79
78
|
|
80
79
|
def model_class(record)
|
81
80
|
return self if record["type"].blank?
|
81
|
+
|
82
82
|
record["type"].constantize
|
83
83
|
end
|
84
84
|
end
|
data/lib/modis/index.rb
CHANGED
@@ -21,14 +21,17 @@ module Modis
|
|
21
21
|
def index(attribute)
|
22
22
|
attribute = attribute.to_s
|
23
23
|
raise IndexError, "No such attribute '#{attribute}'" unless attributes.key?(attribute)
|
24
|
+
|
24
25
|
indexed_attributes << attribute
|
25
26
|
end
|
26
27
|
|
27
28
|
def where(query)
|
28
29
|
raise IndexError, 'Queries using multiple indexes is not currently supported.' if query.keys.size > 1
|
30
|
+
|
29
31
|
attribute, value = query.first
|
30
32
|
ids = index_for(attribute, value)
|
31
33
|
return [] if ids.empty?
|
34
|
+
|
32
35
|
find_all(ids)
|
33
36
|
end
|
34
37
|
|
data/lib/modis/model.rb
CHANGED
data/lib/modis/persistence.rb
CHANGED
@@ -97,13 +97,13 @@ module Modis
|
|
97
97
|
|
98
98
|
private
|
99
99
|
|
100
|
-
def msgpack_array_header(
|
101
|
-
if
|
102
|
-
[0x90 |
|
103
|
-
elsif
|
104
|
-
[0xDC,
|
100
|
+
def msgpack_array_header(values_size)
|
101
|
+
if values_size < 16
|
102
|
+
[0x90 | values_size].pack("C")
|
103
|
+
elsif values_size < 65536
|
104
|
+
[0xDC, values_size].pack("Cn")
|
105
105
|
else
|
106
|
-
[0xDD,
|
106
|
+
[0xDD, values_size].pack("CN")
|
107
107
|
end.force_encoding(Encoding::UTF_8)
|
108
108
|
end
|
109
109
|
end
|
@@ -114,6 +114,7 @@ module Modis
|
|
114
114
|
|
115
115
|
def key
|
116
116
|
return nil if new_record?
|
117
|
+
|
117
118
|
self.class.sti_child? ? self.class.sti_base_key_for(id) : self.class.key_for(id)
|
118
119
|
end
|
119
120
|
|
@@ -157,16 +158,22 @@ module Modis
|
|
157
158
|
save(validate: false)
|
158
159
|
end
|
159
160
|
|
160
|
-
def
|
161
|
+
def update(attrs)
|
161
162
|
assign_attributes(attrs)
|
162
163
|
save
|
163
164
|
end
|
164
165
|
|
165
|
-
|
166
|
+
alias update_attributes update
|
167
|
+
deprecate update_attributes: 'please, use update instead'
|
168
|
+
|
169
|
+
def update!(attrs)
|
166
170
|
assign_attributes(attrs)
|
167
171
|
save!
|
168
172
|
end
|
169
173
|
|
174
|
+
alias update_attributes! update!
|
175
|
+
deprecate update_attributes!: 'please, use update! instead'
|
176
|
+
|
170
177
|
private
|
171
178
|
|
172
179
|
def coerce_for_persistence(value)
|
@@ -178,8 +185,8 @@ module Modis
|
|
178
185
|
validate(args)
|
179
186
|
future = persist
|
180
187
|
|
181
|
-
if future && (future == :unchanged || future.value == 'OK')
|
182
|
-
|
188
|
+
if future && ((future.is_a?(Symbol) && future == :unchanged) || future.value == 'OK')
|
189
|
+
changes_applied
|
183
190
|
@new_record = false
|
184
191
|
true
|
185
192
|
else
|
@@ -190,6 +197,7 @@ module Modis
|
|
190
197
|
def validate(args)
|
191
198
|
skip_validate = args.key?(:validate) && args[:validate] == false
|
192
199
|
return if skip_validate || valid?
|
200
|
+
|
193
201
|
raise Modis::RecordInvalid, errors.full_messages.join(', ')
|
194
202
|
end
|
195
203
|
|
@@ -223,19 +231,18 @@ module Modis
|
|
223
231
|
|
224
232
|
future
|
225
233
|
end
|
234
|
+
# rubocop:enable Metrics/AbcSize, Metrics/PerceivedComplexity
|
226
235
|
|
227
236
|
def coerced_attributes
|
228
237
|
attrs = []
|
229
238
|
|
230
239
|
if new_record?
|
231
240
|
attributes.each do |k, v|
|
232
|
-
if (self.class.attributes[k][:default] || nil) != v
|
233
|
-
attrs << k << coerce_for_persistence(v)
|
234
|
-
end
|
241
|
+
attrs << k << coerce_for_persistence(v) if (self.class.attributes[k][:default] || nil) != v
|
235
242
|
end
|
236
243
|
else
|
237
|
-
changed_attributes.
|
238
|
-
attrs <<
|
244
|
+
changed_attributes.each_key do |key|
|
245
|
+
attrs << key << coerce_for_persistence(attributes[key])
|
239
246
|
end
|
240
247
|
end
|
241
248
|
|
data/lib/modis/version.rb
CHANGED
data/modis.gemspec
CHANGED
@@ -10,7 +10,7 @@ Gem::Specification.new do |gem|
|
|
10
10
|
gem.email = ["port001@gmail.com"]
|
11
11
|
gem.description = "ActiveModel + Redis"
|
12
12
|
gem.summary = "ActiveModel + Redis"
|
13
|
-
gem.homepage = "https://github.com/
|
13
|
+
gem.homepage = "https://github.com/rpush/modis"
|
14
14
|
gem.license = "MIT"
|
15
15
|
|
16
16
|
gem.files = `git ls-files`.split($/)
|
@@ -18,10 +18,11 @@ Gem::Specification.new do |gem|
|
|
18
18
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
19
19
|
gem.require_paths = ["lib"]
|
20
20
|
|
21
|
-
gem.
|
22
|
-
|
21
|
+
gem.required_ruby_version = ">= 2.3.0"
|
22
|
+
|
23
|
+
gem.add_runtime_dependency 'activemodel', '>= 5.2'
|
24
|
+
gem.add_runtime_dependency 'activesupport', '>= 5.2'
|
23
25
|
gem.add_runtime_dependency 'redis', '>= 3.0'
|
24
|
-
gem.add_runtime_dependency 'hiredis', '>= 0.5'
|
25
26
|
gem.add_runtime_dependency 'connection_pool', '>= 2'
|
26
27
|
|
27
28
|
if defined? JRUBY_VERSION
|
@@ -30,4 +31,13 @@ Gem::Specification.new do |gem|
|
|
30
31
|
else
|
31
32
|
gem.add_runtime_dependency 'msgpack', '>= 0.5'
|
32
33
|
end
|
34
|
+
|
35
|
+
gem.add_development_dependency "appraisal"
|
36
|
+
gem.add_development_dependency 'rake'
|
37
|
+
gem.add_development_dependency 'rspec'
|
38
|
+
gem.add_development_dependency 'codeclimate-test-reporter'
|
39
|
+
gem.add_development_dependency 'cane'
|
40
|
+
gem.add_development_dependency 'rubocop', '0.61.1'
|
41
|
+
gem.add_development_dependency 'simplecov'
|
42
|
+
gem.add_development_dependency 'hiredis', '>= 0.5'
|
33
43
|
end
|
data/spec/persistence_spec.rb
CHANGED
@@ -249,7 +249,36 @@ describe Modis::Persistence do
|
|
249
249
|
end
|
250
250
|
end
|
251
251
|
|
252
|
+
describe 'update!' do
|
253
|
+
it 'updates the given attributes' do
|
254
|
+
model.update!(name: 'Derp', age: 29)
|
255
|
+
model.reload
|
256
|
+
expect(model.name).to eq 'Derp'
|
257
|
+
expect(model.age).to eq 29
|
258
|
+
end
|
259
|
+
|
260
|
+
it 'invokes callbacks' do
|
261
|
+
model.update!(name: 'Derp')
|
262
|
+
expect(model.called_callbacks).to_not be_empty
|
263
|
+
end
|
264
|
+
|
265
|
+
it 'updates all dirty attributes' do
|
266
|
+
model.age = 29
|
267
|
+
model.update!(name: 'Derp')
|
268
|
+
model.reload
|
269
|
+
expect(model.age).to eq 29
|
270
|
+
end
|
271
|
+
|
272
|
+
it 'raises an error if the model is invalid' do
|
273
|
+
expect do
|
274
|
+
model.update!(name: nil).to be false
|
275
|
+
end.to raise_error(Modis::RecordInvalid)
|
276
|
+
end
|
277
|
+
end
|
278
|
+
|
252
279
|
describe 'update_attributes!' do
|
280
|
+
around(:each) { |example| ActiveSupport::Deprecation.silence { example.run } }
|
281
|
+
|
253
282
|
it 'updates the given attributes' do
|
254
283
|
model.update_attributes!(name: 'Derp', age: 29)
|
255
284
|
model.reload
|
@@ -276,7 +305,34 @@ describe Modis::Persistence do
|
|
276
305
|
end
|
277
306
|
end
|
278
307
|
|
308
|
+
describe 'update' do
|
309
|
+
it 'updates the given attributes' do
|
310
|
+
model.update(name: 'Derp', age: 29)
|
311
|
+
model.reload
|
312
|
+
expect(model.name).to eq('Derp')
|
313
|
+
expect(model.age).to eq(29)
|
314
|
+
end
|
315
|
+
|
316
|
+
it 'invokes callbacks' do
|
317
|
+
model.update(name: 'Derp')
|
318
|
+
expect(model.called_callbacks).to_not be_empty
|
319
|
+
end
|
320
|
+
|
321
|
+
it 'updates all dirty attributes' do
|
322
|
+
model.age = 29
|
323
|
+
model.update(name: 'Derp')
|
324
|
+
model.reload
|
325
|
+
expect(model.age).to eq(29)
|
326
|
+
end
|
327
|
+
|
328
|
+
it 'returns false if the model is invalid' do
|
329
|
+
expect(model.update(name: nil)).to be false
|
330
|
+
end
|
331
|
+
end
|
332
|
+
|
279
333
|
describe 'update_attributes' do
|
334
|
+
around(:each) { |example| ActiveSupport::Deprecation.silence { example.run } }
|
335
|
+
|
280
336
|
it 'updates the given attributes' do
|
281
337
|
model.update_attributes(name: 'Derp', age: 29)
|
282
338
|
model.reload
|
data/spec/spec_helper.rb
CHANGED
@@ -14,9 +14,7 @@ module SimpleCovHelper
|
|
14
14
|
if ENV['TRAVIS']
|
15
15
|
require 'codeclimate-test-reporter'
|
16
16
|
|
17
|
-
if CodeClimate::TestReporter.run?
|
18
|
-
formatters << CodeClimate::TestReporter::Formatter
|
19
|
-
end
|
17
|
+
formatters << CodeClimate::TestReporter::Formatter if CodeClimate::TestReporter.run?
|
20
18
|
end
|
21
19
|
|
22
20
|
formatter SimpleCov::Formatter::MultiFormatter.new(*formatters)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: modis
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 4.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ian Leitch
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-04-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activemodel
|
@@ -16,28 +16,28 @@ 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: activesupport
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
33
|
+
version: '5.2'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
40
|
+
version: '5.2'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: redis
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -53,7 +53,21 @@ dependencies:
|
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '3.0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
56
|
+
name: connection_pool
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '2'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '2'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: msgpack
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
58
72
|
requirements:
|
59
73
|
- - ">="
|
@@ -67,27 +81,111 @@ dependencies:
|
|
67
81
|
- !ruby/object:Gem::Version
|
68
82
|
version: '0.5'
|
69
83
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
84
|
+
name: appraisal
|
71
85
|
requirement: !ruby/object:Gem::Requirement
|
72
86
|
requirements:
|
73
87
|
- - ">="
|
74
88
|
- !ruby/object:Gem::Version
|
75
|
-
version: '
|
76
|
-
type: :
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
77
91
|
prerelease: false
|
78
92
|
version_requirements: !ruby/object:Gem::Requirement
|
79
93
|
requirements:
|
80
94
|
- - ">="
|
81
95
|
- !ruby/object:Gem::Version
|
82
|
-
version: '
|
96
|
+
version: '0'
|
83
97
|
- !ruby/object:Gem::Dependency
|
84
|
-
name:
|
98
|
+
name: rake
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: rspec
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: codeclimate-test-reporter
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: cane
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - ">="
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0'
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - ">="
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0'
|
153
|
+
- !ruby/object:Gem::Dependency
|
154
|
+
name: rubocop
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - '='
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: 0.61.1
|
160
|
+
type: :development
|
161
|
+
prerelease: false
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - '='
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: 0.61.1
|
167
|
+
- !ruby/object:Gem::Dependency
|
168
|
+
name: simplecov
|
169
|
+
requirement: !ruby/object:Gem::Requirement
|
170
|
+
requirements:
|
171
|
+
- - ">="
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: '0'
|
174
|
+
type: :development
|
175
|
+
prerelease: false
|
176
|
+
version_requirements: !ruby/object:Gem::Requirement
|
177
|
+
requirements:
|
178
|
+
- - ">="
|
179
|
+
- !ruby/object:Gem::Version
|
180
|
+
version: '0'
|
181
|
+
- !ruby/object:Gem::Dependency
|
182
|
+
name: hiredis
|
85
183
|
requirement: !ruby/object:Gem::Requirement
|
86
184
|
requirements:
|
87
185
|
- - ">="
|
88
186
|
- !ruby/object:Gem::Version
|
89
187
|
version: '0.5'
|
90
|
-
type: :
|
188
|
+
type: :development
|
91
189
|
prerelease: false
|
92
190
|
version_requirements: !ruby/object:Gem::Requirement
|
93
191
|
requirements:
|
@@ -103,10 +201,12 @@ extra_rdoc_files: []
|
|
103
201
|
files:
|
104
202
|
- ".gitignore"
|
105
203
|
- ".rubocop.yml"
|
106
|
-
- ".ruby-gemset"
|
107
204
|
- ".ruby-version"
|
108
205
|
- ".travis.yml"
|
206
|
+
- Appraisals
|
207
|
+
- CHANGELOG.md
|
109
208
|
- Gemfile
|
209
|
+
- Gemfile.lock
|
110
210
|
- LICENSE.txt
|
111
211
|
- README.md
|
112
212
|
- Rakefile
|
@@ -114,6 +214,9 @@ files:
|
|
114
214
|
- benchmark/find.rb
|
115
215
|
- benchmark/persistence.rb
|
116
216
|
- benchmark/redis/connection/fakedis.rb
|
217
|
+
- gemfiles/rails_5.2.gemfile
|
218
|
+
- gemfiles/rails_6.0.gemfile
|
219
|
+
- gemfiles/rails_6.1.gemfile
|
117
220
|
- lib/modis.rb
|
118
221
|
- lib/modis/attribute.rb
|
119
222
|
- lib/modis/configuration.rb
|
@@ -136,11 +239,11 @@ files:
|
|
136
239
|
- spec/support/simplecov_quality_formatter.rb
|
137
240
|
- spec/transaction_spec.rb
|
138
241
|
- spec/validations_spec.rb
|
139
|
-
homepage: https://github.com/
|
242
|
+
homepage: https://github.com/rpush/modis
|
140
243
|
licenses:
|
141
244
|
- MIT
|
142
245
|
metadata: {}
|
143
|
-
post_install_message:
|
246
|
+
post_install_message:
|
144
247
|
rdoc_options: []
|
145
248
|
require_paths:
|
146
249
|
- lib
|
@@ -148,16 +251,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
148
251
|
requirements:
|
149
252
|
- - ">="
|
150
253
|
- !ruby/object:Gem::Version
|
151
|
-
version:
|
254
|
+
version: 2.3.0
|
152
255
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
153
256
|
requirements:
|
154
257
|
- - ">="
|
155
258
|
- !ruby/object:Gem::Version
|
156
259
|
version: '0'
|
157
260
|
requirements: []
|
158
|
-
|
159
|
-
|
160
|
-
signing_key:
|
261
|
+
rubygems_version: 3.1.4
|
262
|
+
signing_key:
|
161
263
|
specification_version: 4
|
162
264
|
summary: ActiveModel + Redis
|
163
265
|
test_files:
|
data/.ruby-gemset
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
modis
|