mongoid_listable 0.2.1 → 0.2.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 +8 -8
- data/README.md +31 -18
- data/lib/mongoid/listable/accessors.rb +3 -5
- data/lib/mongoid/listable/callbacks.rb +37 -46
- data/lib/mongoid/listable/macros.rb +22 -12
- data/lib/mongoid/listable/version.rb +1 -1
- data/lib/mongoid/listable.rb +28 -27
- data/spec/models/item.rb +1 -1
- data/spec/mongoid_listable_spec.rb +46 -33
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
YWE5MDIwMmJjOWRhNTM2NzU2Yzg2OWYzYTI4YmM4NGQ3ODczYjg0Mw==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
MDJmNTM5NzAyYjM4MGU2ZjEyZWFiYjY0NmY2YWYzMzEyMDVlYmRlYQ==
|
7
7
|
!binary "U0hBNTEy":
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
M2JhNWFhMjcwNjUxMTE5OGM1MzU1OTZlN2U3NDNiNzI2N2M5MjY5YmQxNWY1
|
10
|
+
MzBiMDkzZDliOTJjNTNkZmQyN2MwYjU3NDhiZGE3NmU3YTdhZmFiYWRmOGU2
|
11
|
+
YzBkNzM3Njg3MTA0ODg2ZTQ5MzY1YTc1YWM4Yzk1Y2NmNWQ5NjQ=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
MGQwYTNkYzcyNjk2OGU3YWMzODliODEyMWY0MzQ4ZTE0MGIyOGRkOTc5MzUx
|
14
|
+
ZjU1OTA4ZGRkOWNiNTc0ZDNhNjYxMTBjNDUyZmRhMThkNzQ4NWY1NTc4Y2Ey
|
15
|
+
NTgwZTU4OTk2NDMwOGQyN2I4MTVmMGFkYzBjNmM5NTUxZjg2ZTg=
|
data/README.md
CHANGED
@@ -1,14 +1,15 @@
|
|
1
1
|
# Mongoid Listable
|
2
|
-
[](https://codeclimate.com/github/richardcalahan/mongoid_listable)
|
3
3
|
[](https://travis-ci.org/richardcalahan/mongoid_listable)
|
4
4
|
[](https://coveralls.io/r/richardcalahan/mongoid_listable?branch=master)
|
5
5
|
[](http://badge.fury.io/rb/mongoid_listable)
|
6
6
|
|
7
|
-
Mongoid Listable
|
7
|
+
Mongoid Listable is a library for managing listable relations. It works great for isolated collections or for more complex `has_many` / `embeds_many` relationships.
|
8
|
+
|
8
9
|
There are two main macros:
|
9
10
|
|
10
|
-
`listed` for
|
11
|
-
`lists` for `has_many` / `
|
11
|
+
* `listed` for non-relational lists that do not belong to any objects.
|
12
|
+
* `lists` for `has_many` / `embeds_many` relationships.
|
12
13
|
|
13
14
|
|
14
15
|
## Basic Usage - Isolated
|
@@ -20,11 +21,23 @@ There are two main macros:
|
|
20
21
|
listed
|
21
22
|
end
|
22
23
|
|
23
|
-
The `listed` macro will assign a `position` field and a `list` scope to the Photo class. All Photo instances
|
24
|
-
|
25
|
-
|
24
|
+
The `listed` macro will assign a `position` field and a `list` scope to the Photo class. All Photo instances that are
|
25
|
+
created, destroyed, or have their position field updated will trigger a reording of all sibling instances.
|
26
|
+
|
27
|
+
Non-relational lists can have as many listed contexts as needed. You'll need to specify both the `scope` and the
|
28
|
+
`field` options in these cases.
|
29
|
+
|
30
|
+
class Photo
|
31
|
+
|
32
|
+
include Mongoid::Document
|
33
|
+
include Mongoid::Listable
|
34
|
+
|
35
|
+
listed :scope :list, field: :position
|
36
|
+
listed :scope :slideshow, field: :slideshow_position
|
37
|
+
|
38
|
+
end
|
26
39
|
|
27
|
-
## Basic Usage - Has Many
|
40
|
+
## Basic Usage - Has Many / Embeds Many
|
28
41
|
|
29
42
|
|
30
43
|
class User
|
@@ -32,6 +45,8 @@ added or removed, (or whose position fields are updated) will trigger automatic
|
|
32
45
|
include Mongoid:Listable
|
33
46
|
|
34
47
|
has_many :photos
|
48
|
+
# or embeds_many :photos
|
49
|
+
|
35
50
|
lists :photos
|
36
51
|
...
|
37
52
|
end
|
@@ -40,11 +55,12 @@ added or removed, (or whose position fields are updated) will trigger automatic
|
|
40
55
|
include Mongoid::Document
|
41
56
|
|
42
57
|
belongs_to :user
|
58
|
+
# or embedded_in :user
|
43
59
|
...
|
44
60
|
end
|
45
61
|
|
46
|
-
In this example photos that are added to or removed from a user, or have their position attribute updated
|
47
|
-
will
|
62
|
+
In this example photos that are added to or removed from a user's collection, or have their position attribute updated
|
63
|
+
will trigger a reordering of all sibling instances. For example:
|
48
64
|
|
49
65
|
# setter
|
50
66
|
User.first.photos = [ photo_a, photo_c, photo_b ]
|
@@ -61,13 +77,14 @@ will maintain logical order based on the method used:
|
|
61
77
|
|
62
78
|
|
63
79
|
|
64
|
-
Each photo that belongs to the user will automatically obtain a field called `user_position`. The field
|
65
|
-
is derived from the foreign key of the relation, replacing "\_id" with "_position".
|
80
|
+
Each photo that belongs to the user will automatically obtain a field called `user_position`. The field name
|
81
|
+
is derived from the foreign key of the relation, replacing "\_id" with "_position". Having a unique position key
|
82
|
+
for each 1-n relationship allows for more complex lists.
|
66
83
|
|
67
|
-
The `has_many`
|
84
|
+
The `has_many` / `embeds_many` relationship of a user to their photos will automadtically be ordered by `user_position` unless otherwise specified
|
68
85
|
via the standard `order` option to the `has_many` macro.
|
69
86
|
|
70
|
-
## Advanced Usage - Has Many
|
87
|
+
## Advanced Usage - Has Many / Embeds Many
|
71
88
|
|
72
89
|
# Handles multiple has_many relations on same model!
|
73
90
|
|
@@ -110,10 +127,6 @@ In this example, there are two `has_many` relations defined between a user and p
|
|
110
127
|
obtain two position fields: `featured_by_user_position` and `kodaked_by_user_position`.
|
111
128
|
|
112
129
|
|
113
|
-
## Todo
|
114
|
-
|
115
|
-
Need to test embedded documents.
|
116
|
-
|
117
130
|
## Installation
|
118
131
|
|
119
132
|
Add this line to your application's Gemfile:
|
@@ -21,7 +21,6 @@ module Mongoid
|
|
21
21
|
redefine_method ids_method do |ids|
|
22
22
|
send meta.setter, meta.klass.find(ids).sort_by_attr(:id, ids)
|
23
23
|
end
|
24
|
-
|
25
24
|
self
|
26
25
|
end
|
27
26
|
|
@@ -37,14 +36,13 @@ module Mongoid
|
|
37
36
|
def set name, meta
|
38
37
|
before_method "#{name}=" do |objects|
|
39
38
|
objects ||= []
|
40
|
-
|
41
|
-
reposition objects,
|
39
|
+
|
40
|
+
reposition objects, position_field_name(meta), 1
|
42
41
|
|
43
42
|
(send(name).to_a - objects).each do |object|
|
44
|
-
object.unset
|
43
|
+
object.unset position_field_name(meta)
|
45
44
|
end
|
46
45
|
end
|
47
|
-
|
48
46
|
self
|
49
47
|
end
|
50
48
|
|
@@ -9,25 +9,20 @@ module Mongoid
|
|
9
9
|
# Defines a mongoid before_create callback.
|
10
10
|
# Sets the position field to current object count + 1
|
11
11
|
#
|
12
|
-
# @param [
|
12
|
+
# @param [ Symbol ] The name of the position field
|
13
13
|
#
|
14
14
|
# @return [ Object ] self
|
15
15
|
#
|
16
16
|
# @since 0.1.0
|
17
17
|
def created name
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
siblings = siblings name
|
23
|
-
reposition siblings.gte(name => position), name, position + 1
|
18
|
+
register_callback name, :before_create do
|
19
|
+
if position = send(name)
|
20
|
+
objects = siblings(name).gte(name => position)
|
21
|
+
reposition objects, name, position + 1
|
24
22
|
else
|
25
23
|
set name, siblings(name).count + 1
|
26
24
|
end
|
27
25
|
end
|
28
|
-
|
29
|
-
before_create callback
|
30
|
-
self
|
31
26
|
end
|
32
27
|
|
33
28
|
# Defines a mongoid before_update callback.
|
@@ -35,41 +30,33 @@ module Mongoid
|
|
35
30
|
# Hoe the change is applied varies depending on the redrection
|
36
31
|
# of the update.
|
37
32
|
#
|
38
|
-
# @param [
|
33
|
+
# @param [ Symbol ] The name of the position field
|
39
34
|
#
|
40
35
|
# @return [ Object ] self
|
41
36
|
#
|
42
37
|
# @since 0.1.0
|
43
38
|
def updated name
|
44
|
-
|
45
|
-
define_method callback do
|
39
|
+
register_callback name, :before_update do
|
46
40
|
apply_change_on name if send("#{name}_changed?")
|
47
41
|
end
|
48
|
-
before_update callback
|
49
|
-
self
|
50
42
|
end
|
51
43
|
|
52
44
|
# Defines a mongoid before_destroy callback.
|
53
45
|
# Resets all sibling object's higher in the list
|
54
46
|
#
|
55
|
-
# @param [
|
47
|
+
# @param [ Symbol ] The name of the position field
|
56
48
|
#
|
57
49
|
# @return [ Object ] self
|
58
50
|
#
|
59
51
|
# @since 0.1.0
|
60
52
|
def destroyed name
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
siblings = siblings(name).gt(name => position)
|
65
|
-
reposition siblings, name, position
|
53
|
+
register_callback name, :before_destroy do
|
54
|
+
siblings = siblings(name).gt(name => send(name))
|
55
|
+
reposition siblings, name, send(name)
|
66
56
|
end
|
67
|
-
|
68
|
-
before_destroy callback
|
69
|
-
self
|
70
57
|
end
|
71
58
|
|
72
|
-
# Defines a mongoid
|
59
|
+
# Defines a mongoid 1-n relation after_add callback.
|
73
60
|
# Sets the position attribute to current relations length + 1
|
74
61
|
#
|
75
62
|
# @param [ Symbol ] name The name of the has_many relation
|
@@ -79,22 +66,19 @@ module Mongoid
|
|
79
66
|
#
|
80
67
|
# @since 0.0.6
|
81
68
|
def added name, meta
|
82
|
-
|
83
|
-
define_method callback do |object|
|
69
|
+
register_callback name, :after_add do |object|
|
84
70
|
return unless object.new_record?
|
85
|
-
field_name =
|
71
|
+
field_name = position_field_name meta
|
86
72
|
if position = object.send(field_name)
|
87
73
|
objects = object.siblings(field_name).gte(field_name => position)
|
88
74
|
reposition objects, field_name, position + 1
|
89
75
|
else
|
90
|
-
object.set field_name,
|
76
|
+
object.set field_name, many(name).count
|
91
77
|
end
|
92
78
|
end
|
93
|
-
meta[:after_add] = callback
|
94
|
-
self
|
95
79
|
end
|
96
80
|
|
97
|
-
# Defines a mongoid
|
81
|
+
# Defines a mongoid 1-n relation before_remove callback.
|
98
82
|
# Resets the position index on all objects that came after
|
99
83
|
#
|
100
84
|
# @param [ Symbol ] name The name of the has_many relation
|
@@ -103,17 +87,25 @@ module Mongoid
|
|
103
87
|
# @return [ Object ] self
|
104
88
|
#
|
105
89
|
# @since 0.0.6
|
106
|
-
def removed name, meta
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
reposition object.
|
112
|
-
field_name
|
113
|
-
object.unset field_name
|
90
|
+
def removed name, meta
|
91
|
+
register_callback name, :before_remove do |object|
|
92
|
+
field_name = position_field_name meta
|
93
|
+
objects = object.siblings(field_name)
|
94
|
+
.gt(field_name => object.send(field_name))
|
95
|
+
reposition objects, field_name, object.send(field_name)
|
96
|
+
object.unset field_name
|
114
97
|
end
|
98
|
+
end
|
99
|
+
|
100
|
+
private
|
101
|
+
|
102
|
+
def register_callback name, hook, &block
|
103
|
+
meta = reflect_on_association name
|
104
|
+
callback = "#{hook}_#{name}"
|
105
|
+
|
106
|
+
define_method callback, &block
|
115
107
|
|
116
|
-
meta[
|
108
|
+
meta ? meta[hook] = callback : send(hook, callback)
|
117
109
|
self
|
118
110
|
end
|
119
111
|
|
@@ -121,19 +113,18 @@ module Mongoid
|
|
121
113
|
|
122
114
|
private
|
123
115
|
|
124
|
-
# Applies a position change on
|
116
|
+
# Applies a position change on field. Which objects are repositioned
|
125
117
|
# depends on the direction of the change.
|
126
118
|
#
|
127
|
-
# @param [ Symbol ] name The name of position
|
119
|
+
# @param [ Symbol ] name The name of position field
|
128
120
|
#
|
129
121
|
# @since 0.1.0
|
130
122
|
def apply_change_on name
|
131
123
|
from, to = change_on name
|
132
|
-
siblings = siblings name
|
133
124
|
if to > from
|
134
|
-
reposition siblings.between(name => from..to), name, from
|
125
|
+
reposition siblings(name).between(name => from..to), name, from
|
135
126
|
elsif to < from
|
136
|
-
reposition siblings.between(name => to..from), name, to + 1
|
127
|
+
reposition siblings(name).between(name => to..from), name, to + 1
|
137
128
|
end
|
138
129
|
set name, to
|
139
130
|
end
|
@@ -15,14 +15,22 @@ module Mongoid
|
|
15
15
|
# @return self
|
16
16
|
#
|
17
17
|
# @since 0.1.0
|
18
|
-
def listed
|
19
|
-
|
18
|
+
def listed options={}
|
19
|
+
config = {
|
20
|
+
field: :position,
|
21
|
+
scope: :list
|
22
|
+
}
|
20
23
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
+
config.merge! options
|
25
|
+
|
26
|
+
field config[:field], type: Integer
|
27
|
+
|
28
|
+
created config[:field]
|
29
|
+
updated config[:field]
|
30
|
+
destroyed config[:field]
|
31
|
+
|
32
|
+
scope config[:scope], order_by(config[:field] => :asc)
|
24
33
|
|
25
|
-
scope :list, order_by(:position => :asc)
|
26
34
|
self
|
27
35
|
end
|
28
36
|
|
@@ -34,19 +42,21 @@ module Mongoid
|
|
34
42
|
# @return [ Mongoid:Relations:Metadata ] Instance of metadata
|
35
43
|
#
|
36
44
|
# @since 0.0.1
|
37
|
-
def lists
|
38
|
-
meta
|
45
|
+
def lists association, options={}
|
46
|
+
meta = reflect_on_association association
|
47
|
+
field_name = determine_position_field_name meta
|
39
48
|
|
40
|
-
field_name = field_name(meta)
|
41
49
|
meta.klass.send :field, field_name, type: Integer
|
42
50
|
|
43
|
-
ids_set
|
44
|
-
|
51
|
+
ids_set association, meta
|
52
|
+
set association, meta
|
53
|
+
added association, meta
|
54
|
+
removed association, meta
|
45
55
|
|
46
56
|
meta.klass.send :include, Mongoid::Listable
|
47
57
|
meta.klass.updated(field_name).destroyed(field_name)
|
48
58
|
|
49
|
-
meta[:order] ||= "#{field_name
|
59
|
+
meta[:order] ||= "#{field_name} asc"
|
50
60
|
end
|
51
61
|
|
52
62
|
end
|
data/lib/mongoid/listable.rb
CHANGED
@@ -13,43 +13,29 @@ module Mongoid
|
|
13
13
|
include Mongoid::Listable::Macros
|
14
14
|
end
|
15
15
|
|
16
|
-
|
17
|
-
|
18
|
-
# Generates the position field name using the MetaData class
|
19
|
-
#
|
20
|
-
# @param [ MetaData ] meta The MetaData class
|
21
|
-
#
|
22
|
-
# @return Symbol
|
23
|
-
#
|
24
|
-
# @since 0.0.6
|
25
|
-
def field_name meta
|
26
|
-
(meta.foreign_key.to_s.gsub(/_?id$/, '_position')).to_sym
|
27
|
-
end
|
28
|
-
|
29
|
-
end
|
30
|
-
|
31
|
-
# Proxies to the class level version
|
16
|
+
# Proxies to the class level determine_position_field_name
|
32
17
|
#
|
33
18
|
# @param [ MetaData ] meta The MetaData class
|
34
19
|
# @see Class.field_name
|
35
20
|
#
|
36
21
|
# @since 0.0.6
|
37
|
-
def
|
38
|
-
self.class.
|
22
|
+
def position_field_name meta
|
23
|
+
self.class.determine_position_field_name meta
|
39
24
|
end
|
40
25
|
|
41
|
-
#
|
26
|
+
# Finds unique instances of objects for a given relation
|
42
27
|
# Needed because the mongoid callbacks dont update
|
43
28
|
# has_many relations until after invoked.
|
44
29
|
#
|
45
30
|
# @param [ Symbol ] name The name of the has_many relation
|
46
31
|
#
|
47
|
-
# @since 0.
|
48
|
-
def
|
49
|
-
send(name).uniq(&:id)
|
32
|
+
# @since 0.2.1
|
33
|
+
def many name
|
34
|
+
send(name).uniq(&:id)
|
50
35
|
end
|
51
36
|
|
52
|
-
# Retrieves an object
|
37
|
+
# Retrieves siblings of an object in a list.
|
38
|
+
# Scoped by the position fiels name
|
53
39
|
#
|
54
40
|
# @return [ Array ]
|
55
41
|
#
|
@@ -61,18 +47,33 @@ module Mongoid
|
|
61
47
|
|
62
48
|
private
|
63
49
|
|
64
|
-
# Resets
|
50
|
+
# Resets position field on objects starting at 'start'
|
65
51
|
#
|
66
52
|
# @param [ Array ] objects The objects to interate
|
67
|
-
# @param [ Symbol ] column The
|
53
|
+
# @param [ Symbol ] column The field to update
|
68
54
|
# @param [ Integer ] start The starting position
|
69
55
|
#
|
70
56
|
# @since 0.1.0
|
71
|
-
def reposition objects,
|
57
|
+
def reposition objects, field, start
|
72
58
|
objects.each_with_index do |object, index|
|
73
|
-
object.set
|
59
|
+
object.set field, start + index
|
74
60
|
end
|
75
61
|
end
|
76
62
|
|
63
|
+
module ClassMethods
|
64
|
+
|
65
|
+
# Generates the position field name using the MetaData instance
|
66
|
+
#
|
67
|
+
# @param [ MetaData ] meta The MetaData instance
|
68
|
+
#
|
69
|
+
# @return Symbol
|
70
|
+
#
|
71
|
+
# @since 0.2.1
|
72
|
+
def determine_position_field_name meta
|
73
|
+
(meta.foreign_key.to_s.gsub(/_?id$/, '_position')).to_sym
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
|
77
78
|
end
|
78
79
|
end
|
data/spec/models/item.rb
CHANGED
@@ -10,90 +10,93 @@ describe Mongoid::Listable do
|
|
10
10
|
|
11
11
|
describe 'listed' do
|
12
12
|
|
13
|
+
FIELD = :custom_field
|
14
|
+
SCOPE = :custom_scope
|
15
|
+
|
13
16
|
before :each do
|
14
17
|
Item.destroy_all
|
15
18
|
10.times { Item.create! }
|
16
|
-
end
|
19
|
+
end
|
17
20
|
|
18
21
|
after :each do
|
19
|
-
ensure_order Item.
|
22
|
+
ensure_order Item.send(SCOPE), FIELD
|
20
23
|
end
|
21
24
|
|
22
25
|
it 'should have a position field' do
|
23
|
-
expect(Item.fields.key?(
|
26
|
+
expect(Item.fields.key?(FIELD.to_s)).to be_true
|
24
27
|
end
|
25
28
|
|
26
29
|
it 'should have a list scope' do
|
27
|
-
expect(Item.scopes.key?(
|
30
|
+
expect(Item.scopes.key?(SCOPE)).to be_true
|
28
31
|
end
|
29
32
|
|
30
33
|
it 'should append new object at position 1' do
|
31
|
-
item = Item.create
|
32
|
-
expect(item.
|
34
|
+
item = Item.create FIELD => 1
|
35
|
+
expect(item.send(FIELD)).to eq(1)
|
33
36
|
end
|
34
37
|
|
35
38
|
it 'should append new object at position 5' do
|
36
|
-
item = Item.create
|
37
|
-
expect(item.
|
39
|
+
item = Item.create FIELD => 5
|
40
|
+
expect(item.send(FIELD)).to eq(5)
|
38
41
|
end
|
39
42
|
|
40
43
|
it 'should append new object at end of list' do
|
41
44
|
item = Item.create
|
42
|
-
expect(item.
|
45
|
+
expect(item.send(FIELD)).to eq(11)
|
43
46
|
end
|
44
47
|
|
45
48
|
it 'should maintain order when removing object at position 1' do
|
46
|
-
Item.
|
49
|
+
Item.send(SCOPE).first.destroy
|
47
50
|
end
|
48
51
|
|
49
52
|
it 'should maintain order when removing object at position 5' do
|
50
|
-
Item.where(
|
53
|
+
Item.where(FIELD => 5).destroy
|
51
54
|
end
|
52
55
|
|
53
56
|
it 'should maintain order when removing object at position 10' do
|
54
|
-
Item.
|
57
|
+
Item.send(SCOPE).last.destroy
|
55
58
|
end
|
56
59
|
|
57
60
|
it 'should maintain order when moving object from position 1 to 5' do
|
58
|
-
item = Item.
|
59
|
-
item.update_attribute
|
60
|
-
expect(Item.
|
61
|
+
item = Item.send(SCOPE).first
|
62
|
+
item.update_attribute FIELD, 5
|
63
|
+
expect(Item.send(SCOPE).where(FIELD => 5).first).to eq(item)
|
61
64
|
end
|
62
65
|
|
63
66
|
it 'should maintain order when moving object from position 10 to 5' do
|
64
|
-
item = Item.
|
65
|
-
item.update_attribute
|
66
|
-
expect(Item.
|
67
|
+
item = Item.send(SCOPE).last
|
68
|
+
item.update_attribute FIELD, 5
|
69
|
+
expect(Item.send(SCOPE).where(FIELD => 5).first).to eq(item)
|
67
70
|
end
|
68
71
|
|
69
72
|
it 'should maintain order when moving object from position 2 to 6' do
|
70
|
-
item = Item.
|
71
|
-
item.update_attribute
|
72
|
-
expect(Item.
|
73
|
+
item = Item.send(SCOPE).where(FIELD => 2).first
|
74
|
+
item.update_attribute FIELD, 6
|
75
|
+
expect(Item.send(SCOPE).where(FIELD => 6).first).to eq(item)
|
73
76
|
end
|
74
77
|
|
75
78
|
it 'should maintain order when moving object from position 8 to 4' do
|
76
|
-
item = Item.
|
77
|
-
item.update_attribute
|
78
|
-
expect(Item.
|
79
|
+
item = Item.send(SCOPE).where(FIELD => 8).first
|
80
|
+
item.update_attribute FIELD, 4
|
81
|
+
expect(Item.send(SCOPE).where(FIELD => 4).first).to eq(item)
|
79
82
|
end
|
80
83
|
|
81
84
|
it 'should do nothing when assigning object to same position' do
|
82
|
-
item = Item.
|
83
|
-
item.update_attribute
|
84
|
-
expect(Item.
|
85
|
+
item = Item.send(SCOPE).where(FIELD => 5).first
|
86
|
+
item.update_attribute FIELD, 5
|
87
|
+
expect(Item.send(SCOPE).where(FIELD => 5).first).to eq(item)
|
85
88
|
end
|
86
89
|
|
87
90
|
it 'should compensate for updated positions that are higher than bounds' do
|
88
|
-
item = Item.
|
89
|
-
item.update_attribute
|
90
|
-
expect(Item.
|
91
|
+
item = Item.send(SCOPE).where(FIELD => 5).first
|
92
|
+
item.update_attribute FIELD, 100
|
93
|
+
expect(Item.send(SCOPE).last).to eq(item)
|
91
94
|
end
|
92
95
|
|
93
96
|
it 'should compensate for updated positions that are lower than bounds' do
|
94
|
-
item = Item.
|
95
|
-
item.update_attribute
|
96
|
-
expect(Item.
|
97
|
+
item = Item.send(SCOPE).where(FIELD => 5).first
|
98
|
+
item.update_attribute FIELD, -100
|
99
|
+
expect(Item.send(SCOPE).first).to eq(item)
|
97
100
|
end
|
98
101
|
|
99
102
|
end
|
@@ -145,6 +148,11 @@ describe Mongoid::Listable do
|
|
145
148
|
Article.first.sections.first.destroy
|
146
149
|
end
|
147
150
|
|
151
|
+
it 'should maintain order when removing object at position 2' do
|
152
|
+
section = Article.first.sections.where(article_position: 2).first
|
153
|
+
Article.first.sections.delete(section)
|
154
|
+
end
|
155
|
+
|
148
156
|
it 'should maintain order when removing object at position 5' do
|
149
157
|
Article.first.sections.where(article_position: 5).first.destroy
|
150
158
|
end
|
@@ -258,6 +266,11 @@ describe Mongoid::Listable do
|
|
258
266
|
User.first.photos.first.destroy
|
259
267
|
end
|
260
268
|
|
269
|
+
it 'should maintain order when removing object at position 2' do
|
270
|
+
photo = User.first.photos.where(user_position: 2).first
|
271
|
+
User.first.photos.delete(photo)
|
272
|
+
end
|
273
|
+
|
261
274
|
it 'should maintain order when removing object at position 5' do
|
262
275
|
User.first.photos.where(user_position: 5).first.destroy
|
263
276
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mongoid_listable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- richardcalahan
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-11-
|
11
|
+
date: 2013-11-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: mongoid
|