mongoid_orderable 6.0.2 → 6.0.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 +4 -4
- data/CHANGELOG.md +6 -1
- data/README.md +21 -2
- data/lib/mongoid/orderable/configs/field_config.rb +2 -0
- data/lib/mongoid/orderable/generators/helpers.rb +8 -0
- data/lib/mongoid/orderable/generators/lock_collection.rb +2 -0
- data/lib/mongoid/orderable/handlers/base.rb +24 -2
- data/lib/mongoid/orderable/installer.rb +1 -1
- data/lib/mongoid/orderable/version.rb +1 -1
- data/spec/integration/conditional_spec.rb +36 -0
- data/spec/support/models.rb +12 -0
- metadata +7 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8882038ec4e57486bd693bc1732f935f2d01f949aeedc7f71b3c54bca5ac0b44
|
4
|
+
data.tar.gz: c0c82c4802280dfe6005e89122e9f7905fabcdf261bc9b3864016d10a70c112c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 64332b6ae9d7786864d238accdd3ec81c8defa059ff1d7e1763e487a271c2dffb2f25b3a1a2332947a3b262ecc6cb8da33aae0acdab0cd04bd3ac6e0a2a2ca44
|
7
|
+
data.tar.gz: 918ea29f2b71caf6cfba5cdc7e145bba69d0d90d2561e1983676fa13a3517f87eaabd7f66d628fbae1ec45df56fe82a11a723de632bbd1650697f39939d10534
|
data/CHANGELOG.md
CHANGED
@@ -1,7 +1,12 @@
|
|
1
|
-
### 6.0.
|
1
|
+
### 6.0.4 (Next)
|
2
2
|
|
3
3
|
* Your contribution here.
|
4
4
|
|
5
|
+
### 6.0.3 (2021/06/27)
|
6
|
+
|
7
|
+
* [#72](https://github.com/mongoid/mongoid_orderable/pull/72): Feature: Add :if and :unless conditions which disable callbacks.
|
8
|
+
* [#71](https://github.com/mongoid/mongoid_orderable/pull/71): Fix: Add TTL index to locks table.
|
9
|
+
|
5
10
|
### 6.0.2 (2021/01/26)
|
6
11
|
|
7
12
|
* [#70](https://github.com/mongoid/mongoid_orderable/pull/70): Fix: Transactions should not use around callbacks - [@johnnyshields](https://github.com/johnnyshields).
|
data/README.md
CHANGED
@@ -138,7 +138,8 @@ book.previous_#{field}_item
|
|
138
138
|
|
139
139
|
where `#{field}` is either `position` or `serial_no`.
|
140
140
|
|
141
|
-
When a model defines multiple orderable fields, the original helpers are also available and work
|
141
|
+
When a model defines multiple orderable fields, the original helpers are also available and work
|
142
|
+
on the first orderable field.
|
142
143
|
|
143
144
|
```ruby
|
144
145
|
@book1 = Book.create!
|
@@ -181,6 +182,24 @@ end
|
|
181
182
|
To ensure the position is written correctly, you will need to set
|
182
183
|
`cascade_callbacks: true` on the relation.
|
183
184
|
|
185
|
+
### Disable Ordering
|
186
|
+
|
187
|
+
You can disable position tracking for specific documents using the `:if` and `:unless` options.
|
188
|
+
This is in advanced scenarios where you want to control position manually for certain documents.
|
189
|
+
In general, the disable condition should match a specific scope.
|
190
|
+
**Warning:** If used improperly, this will cause your documents to become out-of-order.
|
191
|
+
|
192
|
+
```ruby
|
193
|
+
class Book
|
194
|
+
include Mongoid::Document
|
195
|
+
include Mongoid::Orderable
|
196
|
+
|
197
|
+
field :track_position, type: Boolean
|
198
|
+
|
199
|
+
orderable if: :track_position, unless: -> { created_at < Date.parse('2020-01-01') }
|
200
|
+
end
|
201
|
+
```
|
202
|
+
|
184
203
|
## Transaction Support
|
185
204
|
|
186
205
|
By default, Mongoid Orderable does not guarantee ordering consistency
|
@@ -219,7 +238,7 @@ After `transaction_max_retries` has been exceeded, a
|
|
219
238
|
|
220
239
|
When using transactions, Mongoid Orderable creates a collection
|
221
240
|
`mongoid_orderable_locks` which is used to store temporary lock objects.
|
222
|
-
|
241
|
+
Lock collections use a TTL index which auto-deletes objects older than 1 day.
|
223
242
|
|
224
243
|
You can change the lock collection name globally or per model:
|
225
244
|
|
@@ -17,6 +17,14 @@ module Generators
|
|
17
17
|
field ||= default_orderable_field
|
18
18
|
#{self_class}.orderable_configs[field][:field]
|
19
19
|
end
|
20
|
+
|
21
|
+
def orderable_if(field)
|
22
|
+
#{self_class}.orderable_configs[field][:if]
|
23
|
+
end
|
24
|
+
|
25
|
+
def orderable_unless(field)
|
26
|
+
#{self_class}.orderable_configs[field][:unless]
|
27
|
+
end
|
20
28
|
KLASS
|
21
29
|
|
22
30
|
generate_method(:orderable_inherited_class) do
|
@@ -12,12 +12,14 @@ module Generators
|
|
12
12
|
module Models
|
13
13
|
class #{model_name}
|
14
14
|
include Mongoid::Document
|
15
|
+
include Mongoid::Timestamps::Updated::Short
|
15
16
|
|
16
17
|
store_in collection: :#{collection_name}
|
17
18
|
|
18
19
|
field :scope, type: String
|
19
20
|
|
20
21
|
index({ scope: 1 }, { unique: 1 })
|
22
|
+
index({ updated_at: 1 }, { expire_after_seconds: 86400 })
|
21
23
|
end
|
22
24
|
end
|
23
25
|
KLASS
|
@@ -15,6 +15,8 @@ module Handlers
|
|
15
15
|
delegate :orderable_keys,
|
16
16
|
:orderable_field,
|
17
17
|
:orderable_position,
|
18
|
+
:orderable_if,
|
19
|
+
:orderable_unless,
|
18
20
|
:orderable_scope,
|
19
21
|
:orderable_scope_changed?,
|
20
22
|
:orderable_top,
|
@@ -39,7 +41,7 @@ module Handlers
|
|
39
41
|
end
|
40
42
|
|
41
43
|
def apply_one_position(field, target_position)
|
42
|
-
return unless changed?(field)
|
44
|
+
return unless allowed?(field) && changed?(field)
|
43
45
|
|
44
46
|
set_lock(field) if use_transactions
|
45
47
|
|
@@ -94,6 +96,7 @@ module Handlers
|
|
94
96
|
end
|
95
97
|
|
96
98
|
def remove_one_position(field)
|
99
|
+
return unless allowed?(field)
|
97
100
|
f = orderable_field(field)
|
98
101
|
current = orderable_position(field)
|
99
102
|
set_lock(field) if use_transactions
|
@@ -127,6 +130,25 @@ module Handlers
|
|
127
130
|
target_position
|
128
131
|
end
|
129
132
|
|
133
|
+
def allowed?(field)
|
134
|
+
cond_if = orderable_if(field)
|
135
|
+
cond_unless = orderable_unless(field)
|
136
|
+
|
137
|
+
(cond_if.nil? || resolve_condition(cond_if)) &&
|
138
|
+
(cond_unless.nil? || !resolve_condition(cond_unless))
|
139
|
+
end
|
140
|
+
|
141
|
+
def resolve_condition(condition)
|
142
|
+
case condition
|
143
|
+
when Proc
|
144
|
+
condition.arity.zero? ? doc.instance_exec(&condition) : condition.call(doc)
|
145
|
+
when Symbol
|
146
|
+
doc.send(condition)
|
147
|
+
else
|
148
|
+
condition || false
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
130
152
|
def changed?(field)
|
131
153
|
return true if new_record? || !doc.send(orderable_field(field)) || move_all[field]
|
132
154
|
changeable_keys(field).any? {|f| doc.send("#{f}_changed?") }
|
@@ -153,7 +175,7 @@ module Handlers
|
|
153
175
|
model_name = doc.class.orderable_configs[field][:lock_collection].to_s.singularize.classify
|
154
176
|
model = Mongoid::Orderable::Models.const_get(model_name)
|
155
177
|
attrs = lock_scope(field, generic)
|
156
|
-
model.where(attrs).find_one_and_update(attrs, { upsert: true })
|
178
|
+
model.where(attrs).find_one_and_update(attrs.merge(updated_at: Time.now), { upsert: true })
|
157
179
|
end
|
158
180
|
|
159
181
|
def lock_scope(field, generic = false)
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require_relative '../spec_helper'
|
2
|
+
|
3
|
+
describe ConditionalOrderable do
|
4
|
+
|
5
|
+
shared_examples_for 'conditional_orderable' do
|
6
|
+
|
7
|
+
before :each do
|
8
|
+
ConditionalOrderable.create!(cond_a: false, cond_b: nil)
|
9
|
+
ConditionalOrderable.create!(cond_a: false, cond_b: 1)
|
10
|
+
ConditionalOrderable.create!(cond_a: true, cond_b: 2)
|
11
|
+
ConditionalOrderable.create!(cond_a: false, cond_b: 3)
|
12
|
+
ConditionalOrderable.create!(cond_a: true, cond_b: 4)
|
13
|
+
ConditionalOrderable.create!(cond_a: true, cond_b: 5)
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'should have proper position field' do
|
17
|
+
orderables = ConditionalOrderable.all.sort_by {|x| x.cond_b || 0 }
|
18
|
+
|
19
|
+
expect(orderables.map(&:pos_a)).to eq [nil, nil, 1, nil, 2, 3]
|
20
|
+
expect(orderables.map(&:pos_b)).to eq [nil, 1, 2, 3, 4, nil]
|
21
|
+
expect(orderables.map(&:pos_c)).to eq [1, 2, 3, 4, 5, 6]
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
context 'with transactions' do
|
26
|
+
enable_transactions!
|
27
|
+
|
28
|
+
it_behaves_like 'conditional_orderable'
|
29
|
+
end
|
30
|
+
|
31
|
+
context 'without transactions' do
|
32
|
+
disable_transactions!
|
33
|
+
|
34
|
+
it_behaves_like 'conditional_orderable'
|
35
|
+
end
|
36
|
+
end
|
data/spec/support/models.rb
CHANGED
@@ -13,6 +13,18 @@ class SimpleOrderable
|
|
13
13
|
orderable
|
14
14
|
end
|
15
15
|
|
16
|
+
class ConditionalOrderable
|
17
|
+
include Mongoid::Document
|
18
|
+
include Mongoid::Orderable
|
19
|
+
|
20
|
+
field :cond_a, type: Boolean
|
21
|
+
field :cond_b, type: Integer
|
22
|
+
|
23
|
+
orderable field: :pos_a, if: :cond_a, unless: ->(obj) { obj.cond_b&.<(2) }
|
24
|
+
orderable field: :pos_b, if: -> { cond_b&.<=(4) }
|
25
|
+
orderable field: :pos_c, unless: false
|
26
|
+
end
|
27
|
+
|
16
28
|
class ScopedGroup
|
17
29
|
include Mongoid::Document
|
18
30
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mongoid_orderable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 6.0.
|
4
|
+
version: 6.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- pyromaniac
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-06-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -117,6 +117,7 @@ files:
|
|
117
117
|
- lib/mongoid/orderable/version.rb
|
118
118
|
- lib/mongoid_orderable.rb
|
119
119
|
- spec/integration/concurrency_spec.rb
|
120
|
+
- spec/integration/conditional_spec.rb
|
120
121
|
- spec/integration/customized_spec.rb
|
121
122
|
- spec/integration/embedded_spec.rb
|
122
123
|
- spec/integration/foreign_key_spec.rb
|
@@ -131,7 +132,8 @@ files:
|
|
131
132
|
- spec/spec_helper.rb
|
132
133
|
- spec/support/models.rb
|
133
134
|
homepage: https://github.com/mongoid/mongoid_orderable
|
134
|
-
licenses:
|
135
|
+
licenses:
|
136
|
+
- MIT
|
135
137
|
metadata: {}
|
136
138
|
post_install_message:
|
137
139
|
rdoc_options: []
|
@@ -148,12 +150,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
148
150
|
- !ruby/object:Gem::Version
|
149
151
|
version: '0'
|
150
152
|
requirements: []
|
151
|
-
rubygems_version: 3.
|
153
|
+
rubygems_version: 3.2.9
|
152
154
|
signing_key:
|
153
155
|
specification_version: 4
|
154
156
|
summary: Mongoid orderable list implementation
|
155
157
|
test_files:
|
156
158
|
- spec/integration/concurrency_spec.rb
|
159
|
+
- spec/integration/conditional_spec.rb
|
157
160
|
- spec/integration/customized_spec.rb
|
158
161
|
- spec/integration/embedded_spec.rb
|
159
162
|
- spec/integration/foreign_key_spec.rb
|