mongoid_listable 0.0.8 → 0.1.0
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/lib/mongoid/listable/accessors.rb +2 -1
- data/lib/mongoid/listable/callbacks.rb +58 -5
- data/lib/mongoid/listable/macros.rb +21 -0
- data/lib/mongoid/listable/version.rb +1 -1
- data/lib/mongoid/listable.rb +71 -0
- data/lib/mongoid_listable.rb +3 -0
- data/spec/models/photo.rb +2 -0
- data/spec/mongoid_listable_spec.rb +100 -19
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
M2JkMzNmNGMyODlkMTEwMzRkZjhkNjcwOGE2ZmEyZDU5YmI3NmE2Zg==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
MmJjNDY1OGIyOThmNmNkMTVhN2NiNGQ3YzVkYjkwNTdhMDU2YzkzZQ==
|
7
7
|
!binary "U0hBNTEy":
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
YzBhYmRkYzMwN2FkNDlhZjNkY2Q0MzI1MzAwNmE4ZjFkZTMxMzNjN2VkNmU3
|
10
|
+
MzNkZmUxZTEzZmE3YjA2ZjVhNjgzMmIzMDIwODE2MWI2Yzk3OGMyYmJkYjkz
|
11
|
+
NWFjN2RjYTIzN2I3MmZmYTZmNWI3ZDQyOWEyZDc0YzBhNDUzZmU=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
YzI5MGM3MTZjYjg2MWY3ZjQzNTExNGYzMWJmNzA3ZjFkNWZlZTlmMzdlYjQ4
|
14
|
+
MWVhZWVkMTQ3NGU3ZjFiODI0NTU0NDQ0MWZjNzhkNGM3MGIzMTFiYjliMTRi
|
15
|
+
M2Q4NDk5MWRlODA5MWIyOTdmOWZhZjFiZjYyODg1NDhkNWFlMTg=
|
@@ -35,8 +35,9 @@ module Mongoid
|
|
35
35
|
# @since 0.0.6
|
36
36
|
def _setter name, meta
|
37
37
|
before_method "#{name}=" do |objects|
|
38
|
+
objects ||= []
|
38
39
|
objects.each_with_index do |object, index|
|
39
|
-
object.
|
40
|
+
object.set field_name(meta), index + 1
|
40
41
|
end
|
41
42
|
|
42
43
|
(send(name).to_a - objects).each do |object|
|
@@ -18,9 +18,11 @@ module Mongoid
|
|
18
18
|
def added name, meta
|
19
19
|
callback = "#{name.to_s.singularize}_added"
|
20
20
|
define_method callback do |object|
|
21
|
-
object
|
21
|
+
if object[field_name(meta)].nil?
|
22
|
+
object.set field_name(meta), has_many_count(name) + 1
|
23
|
+
end
|
22
24
|
end
|
23
|
-
meta[:
|
25
|
+
meta[:before_add] = callback
|
24
26
|
self
|
25
27
|
end
|
26
28
|
|
@@ -41,7 +43,7 @@ module Mongoid
|
|
41
43
|
position = object.send field_name
|
42
44
|
send(name).where(field_name.gt => position)
|
43
45
|
.each_with_index do |object, index|
|
44
|
-
object.
|
46
|
+
object.set field_name, position + index
|
45
47
|
end
|
46
48
|
object.unset field_name
|
47
49
|
end
|
@@ -50,9 +52,60 @@ module Mongoid
|
|
50
52
|
self
|
51
53
|
end
|
52
54
|
|
55
|
+
# Defines a mongoid before_create callback.
|
56
|
+
# Sets the position field to current object count + 1
|
57
|
+
#
|
58
|
+
# @param [ Hash ] The configuration hash
|
59
|
+
#
|
60
|
+
# @return [ Object ] self
|
61
|
+
#
|
62
|
+
# @since 0.1.0
|
63
|
+
def created configuration
|
64
|
+
define_method __method__ do
|
65
|
+
set configuration[:column], self.class.count + 1
|
66
|
+
end
|
67
|
+
before_create __method__
|
68
|
+
self
|
69
|
+
end
|
70
|
+
|
71
|
+
# Defines a mongoid before_update callback.
|
72
|
+
# If the position column has changed, apply the change.
|
73
|
+
# Hoe the change is applied varies depending on the redrection
|
74
|
+
# of the update.
|
75
|
+
#
|
76
|
+
# @param [ Hash ] The configuration hash
|
77
|
+
#
|
78
|
+
# @return [ Object ] self
|
79
|
+
#
|
80
|
+
# @since 0.1.0
|
81
|
+
def updated configuration
|
82
|
+
define_method __method__ do
|
83
|
+
column = configuration[:column]
|
84
|
+
apply_change_on column if send("#{column}_changed?")
|
85
|
+
end
|
86
|
+
before_update __method__
|
87
|
+
self
|
88
|
+
end
|
89
|
+
|
90
|
+
# Defines a mongoid before_destroy callback.
|
91
|
+
# Resets all sibling object's higher in the list
|
92
|
+
#
|
93
|
+
# @param [ Hash ] The configuration hash
|
94
|
+
#
|
95
|
+
# @return [ Object ] self
|
96
|
+
#
|
97
|
+
# @since 0.1.0
|
98
|
+
def destroyed configuration
|
99
|
+
define_method __method__ do
|
100
|
+
column = configuration[:column]
|
101
|
+
reposition siblings.gt(column => position), column, position
|
102
|
+
end
|
103
|
+
before_destroy __method__
|
104
|
+
self
|
105
|
+
end
|
106
|
+
|
53
107
|
end
|
54
108
|
|
55
|
-
end
|
56
|
-
|
109
|
+
end
|
57
110
|
end
|
58
111
|
end
|
@@ -8,6 +8,27 @@ module Mongoid
|
|
8
8
|
|
9
9
|
module ClassMethods
|
10
10
|
|
11
|
+
# Macro to set basic position field on an object
|
12
|
+
#
|
13
|
+
# @param [ Hash ] options The options hash
|
14
|
+
#
|
15
|
+
# @return self
|
16
|
+
#
|
17
|
+
# @since 0.1.0
|
18
|
+
def listed options={}
|
19
|
+
configuration = { column: :position }
|
20
|
+
configuration.merge! options if options.is_a?(Hash)
|
21
|
+
|
22
|
+
field configuration[:column], type: Integer
|
23
|
+
|
24
|
+
created(configuration)
|
25
|
+
.updated(configuration)
|
26
|
+
.destroyed(configuration)
|
27
|
+
|
28
|
+
scope :list, order_by(configuration[:column] => :asc)
|
29
|
+
self
|
30
|
+
end
|
31
|
+
|
11
32
|
# Macro to set relation on which to make a list
|
12
33
|
#
|
13
34
|
# @param [ Symbol ] name The name of the has_many relation
|
data/lib/mongoid/listable.rb
CHANGED
@@ -30,6 +30,7 @@ module Mongoid
|
|
30
30
|
|
31
31
|
# Proxies to the class level version
|
32
32
|
#
|
33
|
+
# @param [ MetaData ] meta The MetaData class
|
33
34
|
# @see Class.field_name
|
34
35
|
#
|
35
36
|
# @since 0.0.6
|
@@ -41,10 +42,80 @@ module Mongoid
|
|
41
42
|
# Needed because the mongoid callbacks dont update
|
42
43
|
# has_many relations until after invoked.
|
43
44
|
#
|
45
|
+
# @param [ Symbol ] name The name of the has_many relation
|
46
|
+
#
|
44
47
|
# @since 0.0.7
|
45
48
|
def has_many_count name
|
46
49
|
send(name).uniq(&:id).count
|
47
50
|
end
|
48
51
|
|
52
|
+
private
|
53
|
+
|
54
|
+
# Applies a position change on column. Which objects are repositioned
|
55
|
+
# depends on the direction of the change.
|
56
|
+
#
|
57
|
+
# @param [ Symbol ] name The name of position column
|
58
|
+
#
|
59
|
+
# @since 0.1.0
|
60
|
+
def apply_change_on column
|
61
|
+
from, to = change_on column
|
62
|
+
if to > from
|
63
|
+
reposition siblings.between(column => from..to), column, from
|
64
|
+
elsif to < from
|
65
|
+
reposition siblings.between(column => to..from), column, to + 1
|
66
|
+
end
|
67
|
+
set column, to
|
68
|
+
end
|
69
|
+
|
70
|
+
# Resets column on objects starting at 'start'
|
71
|
+
#
|
72
|
+
# @param [ Array ] objects The objects to interate
|
73
|
+
# @param [ Symbol ] column The column to update
|
74
|
+
# @param [ Integer ] start The starting position
|
75
|
+
#
|
76
|
+
# @since 0.1.0
|
77
|
+
def reposition objects, column, start
|
78
|
+
objects.each_with_index do |object, index|
|
79
|
+
object.set column, start + index
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
# Returns the old and new values for column
|
84
|
+
#
|
85
|
+
# @param [ Symbol ] column The column to retrieve the change
|
86
|
+
# @return [Array] [from, to]
|
87
|
+
#
|
88
|
+
# @since 0.1.0
|
89
|
+
def change_on column
|
90
|
+
from, to = send "#{column}_change"
|
91
|
+
to = safe_to to
|
92
|
+
[from, to]
|
93
|
+
end
|
94
|
+
|
95
|
+
# Ensures the 'to' value is within acceptable bounds
|
96
|
+
#
|
97
|
+
# @param [ Integer ] to The supplied position value
|
98
|
+
# @return [ Integer ] The acceptable position value
|
99
|
+
#
|
100
|
+
# @since 0.1.0
|
101
|
+
def safe_to to
|
102
|
+
if to > self.class.count
|
103
|
+
self.class.count
|
104
|
+
elsif to < 1
|
105
|
+
1
|
106
|
+
else
|
107
|
+
to
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
# Retrieves an object's list siblings
|
112
|
+
#
|
113
|
+
# @return [ Array ]
|
114
|
+
#
|
115
|
+
# @since 0.1.0
|
116
|
+
def siblings
|
117
|
+
self.class.list.ne id: id
|
118
|
+
end
|
119
|
+
|
49
120
|
end
|
50
121
|
end
|
data/lib/mongoid_listable.rb
CHANGED
data/spec/models/photo.rb
CHANGED
@@ -3,41 +3,122 @@ require 'spec_helper'
|
|
3
3
|
describe Mongoid::Listable do
|
4
4
|
|
5
5
|
before :all do
|
6
|
-
|
7
|
-
|
8
|
-
10.times { @photos << Photo.create }
|
6
|
+
User.create!
|
7
|
+
10.times { Photo.create }
|
9
8
|
end
|
10
9
|
|
11
10
|
it 'created a user' do
|
12
|
-
expect(
|
11
|
+
expect(User.first).to be_true
|
13
12
|
end
|
14
13
|
|
15
14
|
it 'created 10 photos' do
|
16
|
-
expect(
|
15
|
+
expect(Photo.count).to eq(10)
|
17
16
|
end
|
18
17
|
|
19
|
-
it '
|
20
|
-
|
21
|
-
expect(@user.photos.count).to eq(@photos.count)
|
18
|
+
it 'added the position field for a photo' do
|
19
|
+
expect(Photo.instance_methods.include?(:position)).to be_true
|
22
20
|
end
|
23
21
|
|
24
|
-
it '
|
25
|
-
|
26
|
-
|
27
|
-
|
22
|
+
it 'orders photos' do
|
23
|
+
Photo.list.each_with_index do |photo, index|
|
24
|
+
expect(photo.position).to eq(index + 1)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'updates photo order on position change higher' do
|
29
|
+
photo_a_id = Photo.list[3].id
|
30
|
+
photo_b_id = Photo.list[7].id
|
31
|
+
|
32
|
+
expect(Photo.find(photo_a_id).position).to eq(4)
|
33
|
+
expect(Photo.find(photo_b_id).position).to eq(8)
|
34
|
+
|
35
|
+
Photo.find(photo_a_id).update_attribute :position, 9
|
36
|
+
|
37
|
+
expect(Photo.find(photo_a_id).position).to eq(9)
|
38
|
+
expect(Photo.find(photo_b_id).position).to eq(7)
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'updates photo order on position change lower' do
|
42
|
+
photo_a_id = Photo.list[5].id
|
43
|
+
photo_b_id = Photo.list[9].id
|
44
|
+
|
45
|
+
expect(Photo.find(photo_a_id).position).to eq(6)
|
46
|
+
expect(Photo.find(photo_b_id).position).to eq(10)
|
47
|
+
|
48
|
+
Photo.find(photo_a_id).update_attribute :position, 2
|
49
|
+
|
50
|
+
expect(Photo.find(photo_a_id).position).to eq(2)
|
51
|
+
expect(Photo.find(photo_b_id).position).to eq(10)
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'updates photo order on photo destroy' do
|
55
|
+
photo_a_id = Photo.list[5].id
|
56
|
+
photo_b_id = Photo.list[9].id
|
57
|
+
|
58
|
+
expect(Photo.find(photo_b_id).position).to eq(10)
|
59
|
+
|
60
|
+
Photo.find(photo_a_id).destroy
|
61
|
+
|
62
|
+
expect(Photo.find(photo_b_id).position).to eq(9)
|
63
|
+
end
|
64
|
+
|
65
|
+
it 'creates a new photo' do
|
66
|
+
Photo.create
|
67
|
+
expect(Photo.all.count).to eq(10)
|
68
|
+
expect(Photo.last.position).to eq(10)
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'adds photos to a user with the default setter' do
|
72
|
+
User.first.photos = Photo.all
|
73
|
+
expect(User.first.photos.count).to eq(10)
|
74
|
+
end
|
75
|
+
|
76
|
+
it 'orders photos for a user' do
|
77
|
+
User.first.photos.each_with_index do |photo, index|
|
78
|
+
expect(photo.user_position).to eq(index + 1)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'removes photos from a user' do
|
83
|
+
User.first.photos = nil
|
84
|
+
expect(User.first.photos.count).to eq(0)
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'adds 5 photos to a user with the default ids setter' do
|
88
|
+
User.first.photo_ids = Photo.all[0..4].map &:id
|
89
|
+
expect(User.first.photos.count).to eq(5)
|
90
|
+
end
|
91
|
+
|
92
|
+
it 'adds all photos to a user with the default ids setter' do
|
93
|
+
User.first.photo_ids = Photo.all.map &:id
|
94
|
+
expect(User.first.photos.count).to eq(10)
|
95
|
+
end
|
96
|
+
|
97
|
+
it 'orders photos for a user' do
|
98
|
+
User.first.photos.each_with_index do |photo, index|
|
99
|
+
expect(photo.user_position).to eq(index + 1)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
it 'adds a new photo to a user' do
|
104
|
+
User.first.photos << Photo.new
|
105
|
+
expect(User.first.photos.count).to eq(11)
|
106
|
+
expect(User.first.photos.last.user_position).to eq(11)
|
28
107
|
end
|
29
108
|
|
30
|
-
it '
|
31
|
-
|
32
|
-
expect(
|
109
|
+
it 'adds a created photo to a user' do
|
110
|
+
User.first.photos << Photo.create
|
111
|
+
expect(User.first.photos.count).to eq(12)
|
112
|
+
expect(User.first.photos.last.user_position).to eq(12)
|
33
113
|
end
|
34
114
|
|
35
|
-
it '
|
36
|
-
|
37
|
-
expect(
|
115
|
+
it 'deletes a photo from a user' do
|
116
|
+
User.first.photos.delete(Photo.all[5])
|
117
|
+
expect(User.first.photos.count).to eq(11)
|
118
|
+
expect(User.first.photos.last.user_position).to eq(11)
|
38
119
|
end
|
39
120
|
|
40
|
-
it '
|
121
|
+
it 'orders photos for a user' do
|
41
122
|
User.first.photos.each_with_index do |photo, index|
|
42
123
|
expect(photo.user_position).to eq(index + 1)
|
43
124
|
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.0
|
4
|
+
version: 0.1.0
|
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-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: mongoid
|