modis 2.0.0 → 3.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: d72c95fa261834b9a837e642e63e3ef9094e6a00
4
- data.tar.gz: d43a8f952fc05fc725adc94354d77ef4d8318a98
2
+ SHA256:
3
+ metadata.gz: 3a3bc55800857e6cd1042d6ae44ba41f53470bf1d73aaa9d3f7b32c3e2590615
4
+ data.tar.gz: 9697070b178e1b337eb136edfd54b1c45ffd239858d5f34fe8a02fe42b3e4632
5
5
  SHA512:
6
- metadata.gz: 8cf44d0818eb8c163064cee228732b1d86811b08475c033f45b90a4b23cc8e0fc8a1fe030c6822c4ae1e69e7e0873d53a3f0d304572ad3d538ad3d6c18a7490d
7
- data.tar.gz: 1293bc123e53195e5cc5e44c4b77669a52927e5fd6ec3ee20c3523fc3f0ff875905b861a02be07c0f276e2571e951ba35d73d0bf1ef03b59da7139adf3594e00
6
+ metadata.gz: bbc0e35df71570b4dd3d4049865537d24d3b10c10dfd0914b481f5add04ced5e663764720bebf63fad7a29e11227aea9ba4a75c27bcec9061ce5a3f496f33fda
7
+ data.tar.gz: d5bb456a24915dd363c0ecb3af827907b4962fa39f45d9fdd8b72aa36bfc090b921272243379786b444462a3c2dd3f6b516da038d3f2ec2ac812b1f21331fd0f
data/.gitignore CHANGED
@@ -14,4 +14,4 @@ spec/reports
14
14
  test/tmp
15
15
  test/version_tmp
16
16
  tmp
17
- Gemfile.lock
17
+ *.gemfile.lock
@@ -2,6 +2,7 @@ AllCops:
2
2
  Exclude:
3
3
  - modis.gemspec
4
4
  - vendor/**/*
5
+ - gemfiles/**/*
5
6
 
6
7
  LineLength:
7
8
  Enabled: false
@@ -1 +1 @@
1
- 2.4.1
1
+ 2.6.5
@@ -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.2.4
7
- - 2.3.0
8
- - 2.4.0
9
- - jruby-9.1.9.0
11
+ - 2.3
12
+ - 2.4
13
+ - 2.5
14
+ - 2.6
15
+ - 2.7
16
+ - jruby-9.1.17.0
17
+ - jruby-9.2.8.0
18
+
19
+ gemfile:
20
+ - gemfiles/rails_4.2.gemfile
21
+ - gemfiles/rails_5.0.gemfile
22
+ - gemfiles/rails_5.1.gemfile
23
+ - gemfiles/rails_5.2.gemfile
24
+ - gemfiles/rails_6.0.gemfile
25
+
26
+ matrix:
27
+ fast_finish: true
28
+ exclude:
29
+ # Rails 4.2 uses BigDecimal.new which was removed in Ruby 2.7
30
+ - gemfile: gemfiles/rails_4.2.gemfile
31
+ rvm: 2.7
32
+ # Rails 6 requires Ruby 2.5 or higher
33
+ - gemfile: gemfiles/rails_6.0.gemfile
34
+ rvm: 2.3
35
+ - gemfile: gemfiles/rails_6.0.gemfile
36
+ rvm: 2.4
37
+ - gemfile: gemfiles/rails_6.0.gemfile
38
+ rvm: jruby-9.1.17.0
39
+
10
40
  env:
11
41
  global:
12
42
  secure: LrTz0Pq2ibNZuKDhdzcrvEUSNxUpPopEq9aJeCxy3UpV0v4vpHBtWV0S6zofvf98g/RkZ6cGI1u+0H578dHgE6pWTo+iR8LAwqPKofrFIWRkeo+M77Vs5swahb3mQyPOcig1hfVWDm25MsojePYm70eBIcBU55NWImtdePXfiU0=
@@ -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
@@ -0,0 +1,30 @@
1
+ ## Unreleased
2
+
3
+ ## v3.3.0 - 2020-07-07
4
+
5
+ - 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).
6
+
7
+ ## v3.2.0 - 2019-12-12
8
+
9
+ - Add missing `#update` and `#update!`. [#27](https://github.com/rpush/modis/pull/27) by [@dsantosmerino](https://github.com/dsantosmerino).
10
+
11
+ ## v3.1.0 - 2019-10-18
12
+
13
+ - Test with Rails 6
14
+ - Drop i18n dependency (credit goes to [@jas14](https://github.com/jas14) in [#23](https://github.com/rpush/modis/pull/23))
15
+
16
+ ## v3.0.0 - 2018-12-20
17
+
18
+ - Drop support for any Ruby < 2.3 and Rails < 4.2.
19
+ - Add support for Rails 5.2
20
+ - Resolve Rubocop lint violations
21
+ - Test combinations of Ruby and Rails versions in CI
22
+
23
+ ## v2.1.0
24
+
25
+ - Add `enable_all_index` option to allow disabling the `all` keys. [#7](https://github.com/rpush/modis/pull/7)
26
+
27
+ ## v2.0.0
28
+
29
+ - Support MRI 2.2.2+ and JRuby 9k+ [#5](https://github.com/rpush/modis/pull/5)
30
+ - 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
@@ -0,0 +1,96 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ modis (3.3.0)
5
+ activemodel (>= 4.2)
6
+ activesupport (>= 4.2)
7
+ connection_pool (>= 2)
8
+ hiredis (>= 0.5)
9
+ msgpack (>= 0.5)
10
+ redis (>= 3.0)
11
+
12
+ GEM
13
+ remote: https://rubygems.org/
14
+ specs:
15
+ activemodel (6.0.3.2)
16
+ activesupport (= 6.0.3.2)
17
+ activesupport (6.0.3.2)
18
+ concurrent-ruby (~> 1.0, >= 1.0.2)
19
+ i18n (>= 0.7, < 2)
20
+ minitest (~> 5.1)
21
+ tzinfo (~> 1.1)
22
+ zeitwerk (~> 2.2, >= 2.2.2)
23
+ appraisal (2.3.0)
24
+ bundler
25
+ rake
26
+ thor (>= 0.14.0)
27
+ ast (2.4.1)
28
+ cane (3.0.0)
29
+ parallel
30
+ codeclimate-test-reporter (1.0.7)
31
+ simplecov
32
+ concurrent-ruby (1.1.6)
33
+ connection_pool (2.2.3)
34
+ diff-lcs (1.4.4)
35
+ docile (1.3.2)
36
+ hiredis (0.6.3)
37
+ i18n (1.8.3)
38
+ concurrent-ruby (~> 1.0)
39
+ jaro_winkler (1.5.4)
40
+ minitest (5.14.1)
41
+ msgpack (1.3.3)
42
+ parallel (1.19.2)
43
+ parser (2.7.1.4)
44
+ ast (~> 2.4.1)
45
+ powerpack (0.1.2)
46
+ rainbow (3.0.0)
47
+ rake (13.0.1)
48
+ redis (4.2.1)
49
+ rspec (3.9.0)
50
+ rspec-core (~> 3.9.0)
51
+ rspec-expectations (~> 3.9.0)
52
+ rspec-mocks (~> 3.9.0)
53
+ rspec-core (3.9.2)
54
+ rspec-support (~> 3.9.3)
55
+ rspec-expectations (3.9.2)
56
+ diff-lcs (>= 1.2.0, < 2.0)
57
+ rspec-support (~> 3.9.0)
58
+ rspec-mocks (3.9.1)
59
+ diff-lcs (>= 1.2.0, < 2.0)
60
+ rspec-support (~> 3.9.0)
61
+ rspec-support (3.9.3)
62
+ rubocop (0.61.1)
63
+ jaro_winkler (~> 1.5.1)
64
+ parallel (~> 1.10)
65
+ parser (>= 2.5, != 2.5.1.1)
66
+ powerpack (~> 0.1)
67
+ rainbow (>= 2.2.2, < 4.0)
68
+ ruby-progressbar (~> 1.7)
69
+ unicode-display_width (~> 1.4.0)
70
+ ruby-progressbar (1.10.1)
71
+ simplecov (0.18.5)
72
+ docile (~> 1.1)
73
+ simplecov-html (~> 0.11)
74
+ simplecov-html (0.12.2)
75
+ thor (1.0.1)
76
+ thread_safe (0.3.6)
77
+ tzinfo (1.2.7)
78
+ thread_safe (~> 0.1)
79
+ unicode-display_width (1.4.1)
80
+ zeitwerk (2.3.1)
81
+
82
+ PLATFORMS
83
+ ruby
84
+
85
+ DEPENDENCIES
86
+ appraisal
87
+ cane
88
+ codeclimate-test-reporter
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://secure.travis-ci.org/ileitch/modis.png?branch=master)](http://travis-ci.org/ileitch/modis)
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,7 +8,7 @@ ActiveModel + Redis with the aim to mimic ActiveRecord where possible.
8
8
 
9
9
  ## Requirements
10
10
 
11
- Modis supports CRuby 2.2.2+ and jRuby 9k+
11
+ Modis supports any actively supported Ruby and Ruby on Rails versions. As of 2018-12-20, that means CRuby 2.3+ and jRuby 9k+, as well as Rails 4.2+.
12
12
 
13
13
  ## Installation
14
14
 
@@ -28,14 +28,27 @@ Or install it yourself as:
28
28
 
29
29
  ```ruby
30
30
  class MyModel
31
- include Modis::Models
32
- attribute :name, String
33
- attribute :age, Integer
31
+ include Modis::Model
32
+ attribute :name, :string
33
+ attribute :age, :integer
34
34
  end
35
35
 
36
- MyModel.create!(:name => 'Ian', :age => 28)
36
+ MyModel.create!(name: 'Ian', age: 28)
37
37
  ```
38
38
 
39
+ ### all index
40
+
41
+ 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
+
43
+ ```ruby
44
+ class MyModel
45
+ include Modis::Model
46
+ enable_all_index false
47
+ end
48
+ ```
49
+
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/rpush/modis/pull/7 for more context.
51
+
39
52
  ## Supported Features
40
53
 
41
54
  TODO.
@@ -62,7 +62,7 @@ Bench.run do |b|
62
62
  b.report(:update_without_changes) do
63
63
  user = create_user
64
64
  n.times do
65
- user.update_attributes!(name: user.name, age: user.age)
65
+ user.update!(name: user.name, age: user.age)
66
66
  end
67
67
  end
68
68
 
@@ -0,0 +1,8 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "activemodel", "~> 4.2.0"
6
+ gem "activesupport", "~> 4.2.0"
7
+
8
+ gemspec path: "../"
@@ -0,0 +1,8 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "activemodel", "~> 5.0.0"
6
+ gem "activesupport", "~> 5.0.0"
7
+
8
+ gemspec path: "../"
@@ -0,0 +1,8 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "activemodel", "~> 5.1.0"
6
+ gem "activesupport", "~> 5.1.0"
7
+
8
+ gemspec path: "../"
@@ -0,0 +1,8 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "activemodel", "~> 5.2.0"
6
+ gem "activesupport", "~> 5.2.0"
7
+
8
+ gemspec path: "../"
@@ -0,0 +1,8 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "activemodel", "~> 6.0.0"
6
+ gem "activesupport", "~> 6.0.0"
7
+
8
+ gemspec path: "../"
@@ -20,23 +20,32 @@ module Modis
20
20
  @mutex = Mutex.new
21
21
 
22
22
  class << self
23
- attr_accessor :connection_pool, :redis_options, :connection_pool_size,
24
- :connection_pool_timeout
25
- end
23
+ attr_writer :redis_options, :connection_pool_size, :connection_pool_timeout,
24
+ :connection_pool
26
25
 
27
- self.redis_options = { driver: :hiredis }
28
- self.connection_pool_size = 5
29
- self.connection_pool_timeout = 5
26
+ def redis_options
27
+ @redis_options ||= { driver: :hiredis }
28
+ end
30
29
 
31
- def self.connection_pool
32
- return @connection_pool if @connection_pool
33
- @mutex.synchronize do
34
- options = { size: connection_pool_size, timeout: connection_pool_timeout }
35
- @connection_pool = ConnectionPool.new(options) { Redis.new(redis_options) }
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
- def self.with_connection
40
- connection_pool.with { |connection| yield(connection) }
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
@@ -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
- def reset_changes
98
- @changed_attributes = nil
98
+ write_attribute(:type, self.class.name)
99
99
  end
100
100
 
101
101
  def apply_defaults
102
- @attributes = Hash[self.class.attributes_with_defaults]
102
+ @modis_attributes = Hash[self.class.attributes_with_defaults]
103
103
  end
104
104
  end
105
105
  end
@@ -13,6 +13,11 @@ module Modis
13
13
  end
14
14
 
15
15
  def all
16
+ unless all_index_enabled?
17
+ raise IndexError, "Unable to retrieve all records of #{name}, "\
18
+ "because you disabled all index. See :enable_all_index for more."
19
+ end
20
+
16
21
  records = Modis.with_connection do |redis|
17
22
  ids = redis.smembers(key_for(:all))
18
23
  redis.pipelined do
@@ -28,9 +33,7 @@ module Modis
28
33
 
29
34
  attributes = deserialize(record_for(redis, id))
30
35
 
31
- unless attributes['id'].present?
32
- raise RecordNotFound, "Couldn't find #{name} with id=#{id}"
33
- end
36
+ raise RecordNotFound, "Couldn't find #{name} with id=#{id}" unless attributes['id'].present?
34
37
 
35
38
  attributes
36
39
  end
@@ -64,6 +67,7 @@ module Modis
64
67
  def model_for(attributes)
65
68
  cls = model_class(attributes)
66
69
  return unless cls == self || cls < self
70
+
67
71
  cls.new(attributes, new_record: false)
68
72
  end
69
73
 
@@ -74,6 +78,7 @@ module Modis
74
78
 
75
79
  def model_class(record)
76
80
  return self if record["type"].blank?
81
+
77
82
  record["type"].constantize
78
83
  end
79
84
  end
@@ -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
 
@@ -35,9 +35,10 @@ module Modis
35
35
  apply_defaults
36
36
  set_sti_type
37
37
  assign_attributes(record) if record
38
- reset_changes
38
+ changes_applied
39
39
 
40
40
  return unless options.key?(:new_record)
41
+
41
42
  instance_variable_set('@new_record', options[:new_record])
42
43
  end
43
44
 
@@ -61,6 +61,14 @@ module Modis
61
61
  "#{sti_base_absolute_namespace}:#{id}"
62
62
  end
63
63
 
64
+ def enable_all_index(bool)
65
+ @use_all_index = bool
66
+ end
67
+
68
+ def all_index_enabled?
69
+ @use_all_index == true || @use_all_index.nil?
70
+ end
71
+
64
72
  def create(attrs)
65
73
  model = new(attrs)
66
74
  model.save
@@ -89,13 +97,13 @@ module Modis
89
97
 
90
98
  private
91
99
 
92
- def msgpack_array_header(n)
93
- if n < 16
94
- [0x90 | n].pack("C")
95
- elsif n < 65536
96
- [0xDC, n].pack("Cn")
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")
97
105
  else
98
- [0xDD, n].pack("CN")
106
+ [0xDD, values_size].pack("CN")
99
107
  end.force_encoding(Encoding::UTF_8)
100
108
  end
101
109
  end
@@ -106,6 +114,7 @@ module Modis
106
114
 
107
115
  def key
108
116
  return nil if new_record?
117
+
109
118
  self.class.sti_child? ? self.class.sti_base_key_for(id) : self.class.key_for(id)
110
119
  end
111
120
 
@@ -128,8 +137,10 @@ module Modis
128
137
  run_callbacks :destroy do
129
138
  redis.pipelined do
130
139
  remove_from_indexes(redis)
131
- redis.srem(self.class.key_for(:all), id)
132
- redis.srem(self.class.sti_base_key_for(:all), id) if self.class.sti_child?
140
+ if self.class.all_index_enabled?
141
+ redis.srem(self.class.key_for(:all), id)
142
+ redis.srem(self.class.sti_base_key_for(:all), id) if self.class.sti_child?
143
+ end
133
144
  redis.del(key)
134
145
  end
135
146
  end
@@ -147,16 +158,22 @@ module Modis
147
158
  save(validate: false)
148
159
  end
149
160
 
150
- def update_attributes(attrs)
161
+ def update(attrs)
151
162
  assign_attributes(attrs)
152
163
  save
153
164
  end
154
165
 
155
- def update_attributes!(attrs)
166
+ alias update_attributes update
167
+ deprecate update_attributes: 'please, use update instead'
168
+
169
+ def update!(attrs)
156
170
  assign_attributes(attrs)
157
171
  save!
158
172
  end
159
173
 
174
+ alias update_attributes! update!
175
+ deprecate update_attributes!: 'please, use update! instead'
176
+
160
177
  private
161
178
 
162
179
  def coerce_for_persistence(value)
@@ -168,8 +185,8 @@ module Modis
168
185
  validate(args)
169
186
  future = persist
170
187
 
171
- if future && (future == :unchanged || future.value == 'OK')
172
- reset_changes
188
+ if future && ((future.is_a?(Symbol) && future == :unchanged) || future.value == 'OK')
189
+ changes_applied
173
190
  @new_record = false
174
191
  true
175
192
  else
@@ -180,6 +197,7 @@ module Modis
180
197
  def validate(args)
181
198
  skip_validate = args.key?(:validate) && args[:validate] == false
182
199
  return if skip_validate || valid?
200
+
183
201
  raise Modis::RecordInvalid, errors.full_messages.join(', ')
184
202
  end
185
203
 
@@ -198,8 +216,10 @@ module Modis
198
216
  future = attrs.any? ? redis.hmset(key, attrs) : :unchanged
199
217
 
200
218
  if new_record?
201
- redis.sadd(self.class.key_for(:all), id)
202
- redis.sadd(self.class.sti_base_key_for(:all), id) if self.class.sti_child?
219
+ if self.class.all_index_enabled?
220
+ redis.sadd(self.class.key_for(:all), id)
221
+ redis.sadd(self.class.sti_base_key_for(:all), id) if self.class.sti_child?
222
+ end
203
223
  add_to_indexes(redis)
204
224
  else
205
225
  update_indexes(redis)
@@ -211,19 +231,18 @@ module Modis
211
231
 
212
232
  future
213
233
  end
234
+ # rubocop:enable Metrics/AbcSize, Metrics/PerceivedComplexity
214
235
 
215
236
  def coerced_attributes
216
237
  attrs = []
217
238
 
218
239
  if new_record?
219
240
  attributes.each do |k, v|
220
- if (self.class.attributes[k][:default] || nil) != v
221
- attrs << k << coerce_for_persistence(v)
222
- end
241
+ attrs << k << coerce_for_persistence(v) if (self.class.attributes[k][:default] || nil) != v
223
242
  end
224
243
  else
225
- changed_attributes.each do |k, _|
226
- attrs << k << coerce_for_persistence(attributes[k])
244
+ changed_attributes.each_key do |key|
245
+ attrs << key << coerce_for_persistence(attributes[key])
227
246
  end
228
247
  end
229
248
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Modis
4
- VERSION = '2.0.0'
4
+ VERSION = '3.3.0'
5
5
  end
@@ -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/ileitch/modis"
13
+ gem.homepage = "https://github.com/rpush/modis"
14
14
  gem.license = "MIT"
15
15
 
16
16
  gem.files = `git ls-files`.split($/)
@@ -18,8 +18,10 @@ 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.add_runtime_dependency 'activemodel', '>= 3.0'
22
- gem.add_runtime_dependency 'activesupport', '>= 3.0'
21
+ gem.required_ruby_version = ">= 2.3.0"
22
+
23
+ gem.add_runtime_dependency 'activemodel', '>= 4.2'
24
+ gem.add_runtime_dependency 'activesupport', '>= 4.2'
23
25
  gem.add_runtime_dependency 'redis', '>= 3.0'
24
26
  gem.add_runtime_dependency 'hiredis', '>= 0.5'
25
27
  gem.add_runtime_dependency 'connection_pool', '>= 2'
@@ -30,4 +32,12 @@ Gem::Specification.new do |gem|
30
32
  else
31
33
  gem.add_runtime_dependency 'msgpack', '>= 0.5'
32
34
  end
35
+
36
+ gem.add_development_dependency "appraisal"
37
+ gem.add_development_dependency 'rake'
38
+ gem.add_development_dependency 'rspec'
39
+ gem.add_development_dependency 'codeclimate-test-reporter'
40
+ gem.add_development_dependency 'cane'
41
+ gem.add_development_dependency 'rubocop', '0.61.1'
42
+ gem.add_development_dependency 'simplecov'
33
43
  end
@@ -22,6 +22,10 @@ module FindersSpec
22
22
 
23
23
  class Worker < Producer
24
24
  end
25
+
26
+ class UserNoAllIndex < User
27
+ enable_all_index false
28
+ end
25
29
  end
26
30
 
27
31
  describe Modis::Finder do
@@ -67,6 +71,12 @@ describe Modis::Finder do
67
71
  model.destroy
68
72
  expect(FindersSpec::User.all).to eq([])
69
73
  end
74
+
75
+ it 'throws error when enable_all_index option is set to false' do
76
+ FindersSpec::UserNoAllIndex.create!(name: 'Yana')
77
+ expect { FindersSpec::UserNoAllIndex.all }
78
+ .to raise_error(Modis::IndexError)
79
+ end
70
80
  end
71
81
 
72
82
  it 'identifies a found record as not being new' do
@@ -47,6 +47,10 @@ module PersistenceSpec
47
47
  called_callbacks << :test_before_save
48
48
  end
49
49
  end
50
+
51
+ class MockModelNoAllIndex < MockModel
52
+ enable_all_index false
53
+ end
50
54
  end
51
55
 
52
56
  describe Modis::Persistence do
@@ -245,7 +249,36 @@ describe Modis::Persistence do
245
249
  end
246
250
  end
247
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
+
248
279
  describe 'update_attributes!' do
280
+ around(:each) { |example| ActiveSupport::Deprecation.silence { example.run } }
281
+
249
282
  it 'updates the given attributes' do
250
283
  model.update_attributes!(name: 'Derp', age: 29)
251
284
  model.reload
@@ -272,7 +305,34 @@ describe Modis::Persistence do
272
305
  end
273
306
  end
274
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
+
275
333
  describe 'update_attributes' do
334
+ around(:each) { |example| ActiveSupport::Deprecation.silence { example.run } }
335
+
276
336
  it 'updates the given attributes' do
277
337
  model.update_attributes(name: 'Derp', age: 29)
278
338
  model.reload
@@ -296,4 +356,22 @@ describe Modis::Persistence do
296
356
  expect(model.update_attributes(name: nil)).to be false
297
357
  end
298
358
  end
359
+
360
+ describe 'key for all records' do
361
+ let(:all_key_name) { "#{PersistenceSpec::MockModel.absolute_namespace}:all" }
362
+
363
+ describe 'when :enable_all_index option is set to false' do
364
+ it 'does not save new record to the *:all key' do
365
+ model = PersistenceSpec::MockModel.create!(name: 'Sage')
366
+ expect(Redis.new.smembers(all_key_name).map(&:to_i)).to include(model.id)
367
+ end
368
+ end
369
+
370
+ describe 'when :enable_all_index option is set to false' do
371
+ it 'does not save new record to the *:all key' do
372
+ model = PersistenceSpec::MockModelNoAllIndex.create!(name: 'Alex')
373
+ expect(Redis.new.smembers(all_key_name).map(&:to_i)).to_not include(model.id)
374
+ end
375
+ end
376
+ end
299
377
  end
@@ -3,7 +3,7 @@
3
3
  unless ENV['TRAVIS']
4
4
  begin
5
5
  require './spec/support/simplecov_helper'
6
- include SimpleCovHelper
6
+ include SimpleCovHelper # rubocop:disable Style/MixinUsage
7
7
  start_simple_cov('unit')
8
8
  rescue LoadError
9
9
  puts "Coverage disabled."
@@ -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: 2.0.0
4
+ version: 3.3.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: 2017-05-25 00:00:00.000000000 Z
11
+ date: 2020-07-07 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: '3.0'
19
+ version: '4.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: '3.0'
26
+ version: '4.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: '3.0'
33
+ version: '4.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: '3.0'
40
+ version: '4.2'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: redis
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -94,6 +94,104 @@ dependencies:
94
94
  - - ">="
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0.5'
97
+ - !ruby/object:Gem::Dependency
98
+ name: appraisal
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: rake
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: rspec
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: codeclimate-test-reporter
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: cane
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - ">="
158
+ - !ruby/object:Gem::Version
159
+ version: '0'
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - ">="
165
+ - !ruby/object:Gem::Version
166
+ version: '0'
167
+ - !ruby/object:Gem::Dependency
168
+ name: rubocop
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - '='
172
+ - !ruby/object:Gem::Version
173
+ version: 0.61.1
174
+ type: :development
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - '='
179
+ - !ruby/object:Gem::Version
180
+ version: 0.61.1
181
+ - !ruby/object:Gem::Dependency
182
+ name: simplecov
183
+ requirement: !ruby/object:Gem::Requirement
184
+ requirements:
185
+ - - ">="
186
+ - !ruby/object:Gem::Version
187
+ version: '0'
188
+ type: :development
189
+ prerelease: false
190
+ version_requirements: !ruby/object:Gem::Requirement
191
+ requirements:
192
+ - - ">="
193
+ - !ruby/object:Gem::Version
194
+ version: '0'
97
195
  description: ActiveModel + Redis
98
196
  email:
99
197
  - port001@gmail.com
@@ -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,11 @@ files:
114
214
  - benchmark/find.rb
115
215
  - benchmark/persistence.rb
116
216
  - benchmark/redis/connection/fakedis.rb
217
+ - gemfiles/rails_4.2.gemfile
218
+ - gemfiles/rails_5.0.gemfile
219
+ - gemfiles/rails_5.1.gemfile
220
+ - gemfiles/rails_5.2.gemfile
221
+ - gemfiles/rails_6.0.gemfile
117
222
  - lib/modis.rb
118
223
  - lib/modis/attribute.rb
119
224
  - lib/modis/configuration.rb
@@ -136,11 +241,11 @@ files:
136
241
  - spec/support/simplecov_quality_formatter.rb
137
242
  - spec/transaction_spec.rb
138
243
  - spec/validations_spec.rb
139
- homepage: https://github.com/ileitch/modis
244
+ homepage: https://github.com/rpush/modis
140
245
  licenses:
141
246
  - MIT
142
247
  metadata: {}
143
- post_install_message:
248
+ post_install_message:
144
249
  rdoc_options: []
145
250
  require_paths:
146
251
  - lib
@@ -148,16 +253,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
148
253
  requirements:
149
254
  - - ">="
150
255
  - !ruby/object:Gem::Version
151
- version: '0'
256
+ version: 2.3.0
152
257
  required_rubygems_version: !ruby/object:Gem::Requirement
153
258
  requirements:
154
259
  - - ">="
155
260
  - !ruby/object:Gem::Version
156
261
  version: '0'
157
262
  requirements: []
158
- rubyforge_project:
159
- rubygems_version: 2.6.11
160
- signing_key:
263
+ rubygems_version: 3.1.3
264
+ signing_key:
161
265
  specification_version: 4
162
266
  summary: ActiveModel + Redis
163
267
  test_files:
@@ -1 +0,0 @@
1
- modis