mongoid_orderable 6.0.5 → 6.0.7
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 +105 -99
- data/LICENSE.txt +20 -20
- data/README.md +296 -275
- data/Rakefile +24 -24
- data/lib/config/locales/en.yml +12 -12
- data/lib/mongoid/orderable/configs/field_config.rb +81 -81
- data/lib/mongoid/orderable/configs/global_config.rb +26 -26
- data/lib/mongoid/orderable/errors/invalid_target_position.rb +19 -19
- data/lib/mongoid/orderable/errors/transaction_failed.rb +20 -20
- data/lib/mongoid/orderable/generators/base.rb +21 -21
- data/lib/mongoid/orderable/generators/helpers.rb +37 -37
- data/lib/mongoid/orderable/generators/listable.rb +41 -41
- data/lib/mongoid/orderable/generators/lock_collection.rb +39 -39
- data/lib/mongoid/orderable/generators/movable.rb +62 -62
- data/lib/mongoid/orderable/generators/position.rb +26 -26
- data/lib/mongoid/orderable/generators/scope.rb +26 -26
- data/lib/mongoid/orderable/handlers/base.rb +218 -215
- data/lib/mongoid/orderable/handlers/document.rb +32 -32
- data/lib/mongoid/orderable/handlers/document_embedded.rb +14 -14
- data/lib/mongoid/orderable/handlers/document_transactional.rb +32 -32
- data/lib/mongoid/orderable/handlers/transaction.rb +75 -75
- data/lib/mongoid/orderable/installer.rb +64 -64
- data/lib/mongoid/orderable/mixins/callbacks.rb +45 -45
- data/lib/mongoid/orderable/mixins/cascadeable.rb +15 -15
- data/lib/mongoid/orderable/mixins/helpers.rb +45 -39
- data/lib/mongoid/orderable/mixins/listable.rb +49 -49
- data/lib/mongoid/orderable/mixins/movable.rb +64 -64
- data/lib/mongoid/orderable/version.rb +7 -7
- data/lib/mongoid/orderable.rb +29 -29
- data/lib/mongoid_orderable.rb +34 -33
- metadata +3 -3
|
@@ -1,32 +1,32 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Mongoid
|
|
4
|
-
module Orderable
|
|
5
|
-
module Handlers
|
|
6
|
-
class Document < Base
|
|
7
|
-
def before_create
|
|
8
|
-
set_new_record_positions
|
|
9
|
-
apply_all_positions
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
def after_create
|
|
13
|
-
reset
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
def before_update
|
|
17
|
-
return unless any_field_changed?
|
|
18
|
-
apply_all_positions
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
def after_update
|
|
22
|
-
reset
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
def after_destroy
|
|
26
|
-
remove_all_positions
|
|
27
|
-
reset
|
|
28
|
-
end
|
|
29
|
-
end
|
|
30
|
-
end
|
|
31
|
-
end
|
|
32
|
-
end
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Mongoid
|
|
4
|
+
module Orderable
|
|
5
|
+
module Handlers
|
|
6
|
+
class Document < Base
|
|
7
|
+
def before_create
|
|
8
|
+
set_new_record_positions
|
|
9
|
+
apply_all_positions
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def after_create
|
|
13
|
+
reset
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def before_update
|
|
17
|
+
return unless any_field_changed?
|
|
18
|
+
apply_all_positions
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def after_update
|
|
22
|
+
reset
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def after_destroy
|
|
26
|
+
remove_all_positions
|
|
27
|
+
reset
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Mongoid
|
|
4
|
-
module Orderable
|
|
5
|
-
module Handlers
|
|
6
|
-
class DocumentEmbedded < Document
|
|
7
|
-
def after_destroy
|
|
8
|
-
return if doc._root.destroyed?
|
|
9
|
-
super
|
|
10
|
-
end
|
|
11
|
-
end
|
|
12
|
-
end
|
|
13
|
-
end
|
|
14
|
-
end
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Mongoid
|
|
4
|
+
module Orderable
|
|
5
|
+
module Handlers
|
|
6
|
+
class DocumentEmbedded < Document
|
|
7
|
+
def after_destroy
|
|
8
|
+
return if doc._root.destroyed?
|
|
9
|
+
super
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -1,32 +1,32 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Mongoid
|
|
4
|
-
module Orderable
|
|
5
|
-
module Handlers
|
|
6
|
-
class DocumentTransactional < Document
|
|
7
|
-
def before_create
|
|
8
|
-
set_new_record_positions
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
def after_create
|
|
12
|
-
apply_all_positions
|
|
13
|
-
super
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
private
|
|
17
|
-
|
|
18
|
-
def apply_all_positions
|
|
19
|
-
with_transaction { super }
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
def use_transactions
|
|
23
|
-
true
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
def with_transaction(&block)
|
|
27
|
-
Mongoid::Orderable::Handlers::Transaction.new(doc).with_transaction(&block)
|
|
28
|
-
end
|
|
29
|
-
end
|
|
30
|
-
end
|
|
31
|
-
end
|
|
32
|
-
end
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Mongoid
|
|
4
|
+
module Orderable
|
|
5
|
+
module Handlers
|
|
6
|
+
class DocumentTransactional < Document
|
|
7
|
+
def before_create
|
|
8
|
+
set_new_record_positions
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def after_create
|
|
12
|
+
apply_all_positions
|
|
13
|
+
super
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
private
|
|
17
|
+
|
|
18
|
+
def apply_all_positions
|
|
19
|
+
with_transaction { super }
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def use_transactions
|
|
23
|
+
true
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def with_transaction(&block)
|
|
27
|
+
Mongoid::Orderable::Handlers::Transaction.new(doc).with_transaction(&block)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -1,75 +1,75 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Mongoid
|
|
4
|
-
module Orderable
|
|
5
|
-
module Handlers
|
|
6
|
-
# Executes a block within the context of a MongoDB transaction.
|
|
7
|
-
class Transaction
|
|
8
|
-
THREAD_KEY = :__mongoid_orderable_in_txn
|
|
9
|
-
RETRY_SLEEP = 0.001
|
|
10
|
-
|
|
11
|
-
attr_reader :doc
|
|
12
|
-
|
|
13
|
-
def initialize(doc)
|
|
14
|
-
@doc = doc
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
def with_transaction(&block)
|
|
18
|
-
query_cache.uncached do
|
|
19
|
-
if Thread.current[THREAD_KEY]
|
|
20
|
-
yield
|
|
21
|
-
else
|
|
22
|
-
Thread.current[THREAD_KEY] = true
|
|
23
|
-
retries = transaction_max_retries
|
|
24
|
-
begin
|
|
25
|
-
do_transaction(&block)
|
|
26
|
-
rescue Mongo::Error::OperationFailure => e
|
|
27
|
-
sleep(RETRY_SLEEP)
|
|
28
|
-
retries -= 1
|
|
29
|
-
retry if retries >= 0
|
|
30
|
-
raise Mongoid::Orderable::Errors::TransactionFailed.new(e)
|
|
31
|
-
ensure
|
|
32
|
-
Thread.current[THREAD_KEY] = nil
|
|
33
|
-
end
|
|
34
|
-
end
|
|
35
|
-
end
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
private
|
|
39
|
-
|
|
40
|
-
def do_transaction(&_block)
|
|
41
|
-
doc.class.with_session(session_opts) do |session|
|
|
42
|
-
doc.class.with(persistence_opts) do
|
|
43
|
-
session.start_transaction(transaction_opts)
|
|
44
|
-
yield
|
|
45
|
-
session.commit_transaction
|
|
46
|
-
end
|
|
47
|
-
end
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
def session_opts
|
|
51
|
-
{ read: { mode: :primary },
|
|
52
|
-
causal_consistency: true }
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
def persistence_opts
|
|
56
|
-
{ read: { mode: :primary } }
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
def transaction_opts
|
|
60
|
-
{ read: { mode: :primary },
|
|
61
|
-
read_concern: { level: 'majority' },
|
|
62
|
-
write_concern: { w: 'majority' } }
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
def transaction_max_retries
|
|
66
|
-
doc.orderable_keys.map {|k| doc.class.orderable_configs.dig(k, :transaction_max_retries) }.compact.max
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
def query_cache
|
|
70
|
-
defined?(Mongo::QueryCache) ? Mongo::QueryCache : Mongoid::QueryCache
|
|
71
|
-
end
|
|
72
|
-
end
|
|
73
|
-
end
|
|
74
|
-
end
|
|
75
|
-
end
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Mongoid
|
|
4
|
+
module Orderable
|
|
5
|
+
module Handlers
|
|
6
|
+
# Executes a block within the context of a MongoDB transaction.
|
|
7
|
+
class Transaction
|
|
8
|
+
THREAD_KEY = :__mongoid_orderable_in_txn
|
|
9
|
+
RETRY_SLEEP = 0.001
|
|
10
|
+
|
|
11
|
+
attr_reader :doc
|
|
12
|
+
|
|
13
|
+
def initialize(doc)
|
|
14
|
+
@doc = doc
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def with_transaction(&block)
|
|
18
|
+
query_cache.uncached do
|
|
19
|
+
if Thread.current[THREAD_KEY]
|
|
20
|
+
yield
|
|
21
|
+
else
|
|
22
|
+
Thread.current[THREAD_KEY] = true
|
|
23
|
+
retries = transaction_max_retries
|
|
24
|
+
begin
|
|
25
|
+
do_transaction(&block)
|
|
26
|
+
rescue Mongo::Error::OperationFailure => e
|
|
27
|
+
sleep(RETRY_SLEEP)
|
|
28
|
+
retries -= 1
|
|
29
|
+
retry if retries >= 0
|
|
30
|
+
raise Mongoid::Orderable::Errors::TransactionFailed.new(e)
|
|
31
|
+
ensure
|
|
32
|
+
Thread.current[THREAD_KEY] = nil
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
private
|
|
39
|
+
|
|
40
|
+
def do_transaction(&_block)
|
|
41
|
+
doc.class.with_session(session_opts) do |session|
|
|
42
|
+
doc.class.with(persistence_opts) do
|
|
43
|
+
session.start_transaction(transaction_opts)
|
|
44
|
+
yield
|
|
45
|
+
session.commit_transaction
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def session_opts
|
|
51
|
+
{ read: { mode: :primary },
|
|
52
|
+
causal_consistency: true }
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def persistence_opts
|
|
56
|
+
{ read: { mode: :primary } }
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def transaction_opts
|
|
60
|
+
{ read: { mode: :primary },
|
|
61
|
+
read_concern: { level: 'majority' },
|
|
62
|
+
write_concern: { w: 'majority' } }
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def transaction_max_retries
|
|
66
|
+
doc.orderable_keys.map {|k| doc.class.orderable_configs.dig(k, :transaction_max_retries) }.compact.max
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def query_cache
|
|
70
|
+
defined?(Mongo::QueryCache) ? Mongo::QueryCache : Mongoid::QueryCache
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
@@ -1,64 +1,64 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Mongoid
|
|
4
|
-
module Orderable
|
|
5
|
-
class Installer
|
|
6
|
-
attr_reader :klass, :config
|
|
7
|
-
|
|
8
|
-
def initialize(klass, options = {})
|
|
9
|
-
@klass = klass
|
|
10
|
-
@config = Mongoid::Orderable::Configs::FieldConfig.new(klass, options).options
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
def setup
|
|
14
|
-
add_db_field
|
|
15
|
-
add_db_index if config[:index]
|
|
16
|
-
save_config
|
|
17
|
-
include_mixins
|
|
18
|
-
generate_all_helpers
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
private
|
|
22
|
-
|
|
23
|
-
def field_name
|
|
24
|
-
config[:field_options][:as] || config[:field]
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
def order_scope
|
|
28
|
-
config[:scope]
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
def add_db_field
|
|
32
|
-
klass.field(config[:field], { type: Integer }.reverse_merge(config[:field_options]))
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
def add_db_index
|
|
36
|
-
spec = [[config[:field], 1]]
|
|
37
|
-
config[:scope].each {|field| spec.unshift([field, 1]) } if config[:scope].is_a?(Array)
|
|
38
|
-
klass.index(spec.to_h)
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
def save_config
|
|
42
|
-
klass.orderable_configs ||= {}
|
|
43
|
-
klass.orderable_configs = klass.orderable_configs.merge(field_name => config)
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
def include_mixins
|
|
47
|
-
klass.send :include, Mixins::Helpers
|
|
48
|
-
klass.send :include, Mixins::Callbacks
|
|
49
|
-
klass.send :include, Mixins::Movable
|
|
50
|
-
klass.send :include, Mixins::Listable
|
|
51
|
-
klass.send :prepend, Mixins::Cascadeable if klass.embedded?
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
def generate_all_helpers
|
|
55
|
-
Generators::Scope.new(klass).generate(field_name, order_scope)
|
|
56
|
-
Generators::Position.new(klass).generate(field_name)
|
|
57
|
-
Generators::Movable.new(klass).generate(field_name)
|
|
58
|
-
Generators::Listable.new(klass).generate(field_name)
|
|
59
|
-
Generators::Helpers.new(klass).generate
|
|
60
|
-
Generators::LockCollection.new.generate(config[:lock_collection])
|
|
61
|
-
end
|
|
62
|
-
end
|
|
63
|
-
end
|
|
64
|
-
end
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Mongoid
|
|
4
|
+
module Orderable
|
|
5
|
+
class Installer
|
|
6
|
+
attr_reader :klass, :config
|
|
7
|
+
|
|
8
|
+
def initialize(klass, options = {})
|
|
9
|
+
@klass = klass
|
|
10
|
+
@config = Mongoid::Orderable::Configs::FieldConfig.new(klass, options).options
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def setup
|
|
14
|
+
add_db_field
|
|
15
|
+
add_db_index if config[:index]
|
|
16
|
+
save_config
|
|
17
|
+
include_mixins
|
|
18
|
+
generate_all_helpers
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
private
|
|
22
|
+
|
|
23
|
+
def field_name
|
|
24
|
+
config[:field_options][:as] || config[:field]
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def order_scope
|
|
28
|
+
config[:scope]
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def add_db_field
|
|
32
|
+
klass.field(config[:field], { type: Integer }.reverse_merge(config[:field_options]))
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def add_db_index
|
|
36
|
+
spec = [[config[:field], 1]]
|
|
37
|
+
config[:scope].each {|field| spec.unshift([field, 1]) } if config[:scope].is_a?(Array)
|
|
38
|
+
klass.index(spec.to_h)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def save_config
|
|
42
|
+
klass.orderable_configs ||= {}
|
|
43
|
+
klass.orderable_configs = klass.orderable_configs.merge(field_name => config)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def include_mixins
|
|
47
|
+
klass.send :include, Mixins::Helpers
|
|
48
|
+
klass.send :include, Mixins::Callbacks
|
|
49
|
+
klass.send :include, Mixins::Movable
|
|
50
|
+
klass.send :include, Mixins::Listable
|
|
51
|
+
klass.send :prepend, Mixins::Cascadeable if klass.embedded?
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def generate_all_helpers
|
|
55
|
+
Generators::Scope.new(klass).generate(field_name, order_scope)
|
|
56
|
+
Generators::Position.new(klass).generate(field_name)
|
|
57
|
+
Generators::Movable.new(klass).generate(field_name)
|
|
58
|
+
Generators::Listable.new(klass).generate(field_name)
|
|
59
|
+
Generators::Helpers.new(klass).generate
|
|
60
|
+
Generators::LockCollection.new.generate(config[:lock_collection])
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
@@ -1,45 +1,45 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Mongoid
|
|
4
|
-
module Orderable
|
|
5
|
-
module Mixins
|
|
6
|
-
module Callbacks
|
|
7
|
-
extend ActiveSupport::Concern
|
|
8
|
-
|
|
9
|
-
ORDERABLE_TRANSACTION_KEY = :__mongoid_orderable_in_txn
|
|
10
|
-
|
|
11
|
-
included do
|
|
12
|
-
before_create :orderable_before_create
|
|
13
|
-
after_create :orderable_after_create, prepend: true
|
|
14
|
-
before_update :orderable_before_update
|
|
15
|
-
after_update :orderable_after_update, prepend: true
|
|
16
|
-
after_destroy :orderable_after_destroy, prepend: true
|
|
17
|
-
|
|
18
|
-
delegate :before_create,
|
|
19
|
-
:after_create,
|
|
20
|
-
:before_update,
|
|
21
|
-
:after_update,
|
|
22
|
-
:after_destroy,
|
|
23
|
-
to: :orderable_handler,
|
|
24
|
-
prefix: :orderable
|
|
25
|
-
|
|
26
|
-
private
|
|
27
|
-
|
|
28
|
-
def orderable_handler
|
|
29
|
-
@orderable_handler ||= self.class.orderable_handler_class.new(self)
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
def self.orderable_handler_class
|
|
33
|
-
if embedded?
|
|
34
|
-
Mongoid::Orderable::Handlers::DocumentEmbedded
|
|
35
|
-
elsif orderable_configs.values.any? {|c| c[:use_transactions] }
|
|
36
|
-
Mongoid::Orderable::Handlers::DocumentTransactional
|
|
37
|
-
else
|
|
38
|
-
Mongoid::Orderable::Handlers::Document
|
|
39
|
-
end
|
|
40
|
-
end
|
|
41
|
-
end
|
|
42
|
-
end
|
|
43
|
-
end
|
|
44
|
-
end
|
|
45
|
-
end
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Mongoid
|
|
4
|
+
module Orderable
|
|
5
|
+
module Mixins
|
|
6
|
+
module Callbacks
|
|
7
|
+
extend ActiveSupport::Concern
|
|
8
|
+
|
|
9
|
+
ORDERABLE_TRANSACTION_KEY = :__mongoid_orderable_in_txn
|
|
10
|
+
|
|
11
|
+
included do
|
|
12
|
+
before_create :orderable_before_create
|
|
13
|
+
after_create :orderable_after_create, prepend: true
|
|
14
|
+
before_update :orderable_before_update
|
|
15
|
+
after_update :orderable_after_update, prepend: true
|
|
16
|
+
after_destroy :orderable_after_destroy, prepend: true
|
|
17
|
+
|
|
18
|
+
delegate :before_create,
|
|
19
|
+
:after_create,
|
|
20
|
+
:before_update,
|
|
21
|
+
:after_update,
|
|
22
|
+
:after_destroy,
|
|
23
|
+
to: :orderable_handler,
|
|
24
|
+
prefix: :orderable
|
|
25
|
+
|
|
26
|
+
private
|
|
27
|
+
|
|
28
|
+
def orderable_handler
|
|
29
|
+
@orderable_handler ||= self.class.orderable_handler_class.new(self)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def self.orderable_handler_class
|
|
33
|
+
if embedded?
|
|
34
|
+
Mongoid::Orderable::Handlers::DocumentEmbedded
|
|
35
|
+
elsif orderable_configs.values.any? {|c| c[:use_transactions] }
|
|
36
|
+
Mongoid::Orderable::Handlers::DocumentTransactional
|
|
37
|
+
else
|
|
38
|
+
Mongoid::Orderable::Handlers::Document
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Mongoid
|
|
4
|
-
module Orderable
|
|
5
|
-
module Mixins
|
|
6
|
-
# This is required to trigger callbacks on embedded objects.
|
|
7
|
-
# Otherwise, the #move_to parameter won't work when saving the parent.
|
|
8
|
-
module Cascadeable
|
|
9
|
-
def in_callback_state?(kind)
|
|
10
|
-
super || move_all.present?
|
|
11
|
-
end
|
|
12
|
-
end
|
|
13
|
-
end
|
|
14
|
-
end
|
|
15
|
-
end
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Mongoid
|
|
4
|
+
module Orderable
|
|
5
|
+
module Mixins
|
|
6
|
+
# This is required to trigger callbacks on embedded objects.
|
|
7
|
+
# Otherwise, the #move_to parameter won't work when saving the parent.
|
|
8
|
+
module Cascadeable
|
|
9
|
+
def in_callback_state?(kind)
|
|
10
|
+
super || move_all.present?
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -1,39 +1,45 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Mongoid
|
|
4
|
-
module Orderable
|
|
5
|
-
module Mixins
|
|
6
|
-
module Helpers
|
|
7
|
-
def orderable_keys
|
|
8
|
-
Array(orderable_inherited_class.orderable_configs.try(:keys))
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
def default_orderable_field
|
|
12
|
-
self.class.orderable_configs.detect {|_c, conf| conf[:default] }.try(:first) || orderable_keys.first
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
def orderable_scope(field = nil)
|
|
16
|
-
field ||= default_orderable_field
|
|
17
|
-
|
|
18
|
-
if embedded?
|
|
19
|
-
_parent.send(_association.name).send("orderable_#{field}_scope", self)
|
|
20
|
-
else
|
|
21
|
-
orderable_inherited_class.send("orderable_#{field}_scope", self)
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
def orderable_scope_changed?(field)
|
|
26
|
-
!orderable_scope(field).where(_id: _id).exists?
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
def orderable_bottom(field = nil, in_list = true)
|
|
30
|
-
field ||= default_orderable_field
|
|
31
|
-
f = orderable_field(field)
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
end
|
|
39
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Mongoid
|
|
4
|
+
module Orderable
|
|
5
|
+
module Mixins
|
|
6
|
+
module Helpers
|
|
7
|
+
def orderable_keys
|
|
8
|
+
Array(orderable_inherited_class.orderable_configs.try(:keys))
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def default_orderable_field
|
|
12
|
+
self.class.orderable_configs.detect {|_c, conf| conf[:default] }.try(:first) || orderable_keys.first
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def orderable_scope(field = nil)
|
|
16
|
+
field ||= default_orderable_field
|
|
17
|
+
|
|
18
|
+
if embedded?
|
|
19
|
+
_parent.send(_association.name).send("orderable_#{field}_scope", self)
|
|
20
|
+
else
|
|
21
|
+
orderable_inherited_class.send("orderable_#{field}_scope", self)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def orderable_scope_changed?(field)
|
|
26
|
+
!orderable_scope(field).where(_id: _id).exists?
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def orderable_bottom(field = nil, in_list = true)
|
|
30
|
+
field ||= default_orderable_field
|
|
31
|
+
f = orderable_field(field)
|
|
32
|
+
scope = orderable_scope(field)
|
|
33
|
+
scope = scope.ne(_id: _id) if embedded?
|
|
34
|
+
max = scope.ne(f => nil).max(f)
|
|
35
|
+
if embedded? && in_list && persisted?
|
|
36
|
+
previous_position = send("#{f}_was")
|
|
37
|
+
max = [max, previous_position].compact.max
|
|
38
|
+
end
|
|
39
|
+
return orderable_top(field) unless max
|
|
40
|
+
in_list ? max : max.next
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|