acts_as_list_mongoid 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.
- data/.DS_Store +0 -0
- data/README.markdown +61 -0
- data/Rakefile +22 -0
- data/VERSION +1 -0
- data/example/example.rb +35 -0
- data/init.rb +2 -0
- data/lib/.DS_Store +0 -0
- data/lib/acts_as_list_mongoid.rb +2 -0
- data/lib/init.rb +1 -0
- data/lib/mongoid/acts_as_list.rb +370 -0
- data/model/embedded_item.rb +18 -0
- data/spec/.rspec +1 -0
- data/spec/acts_as_list/embedded/custom_embedded_spec.rb +104 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +10 -0
- metadata +111 -0
data/.DS_Store
ADDED
Binary file
|
data/README.markdown
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
# Mongoid Acts as list
|
2
|
+
|
3
|
+
This is a port of the classic +acts_as_list+ to Mongoid.
|
4
|
+
|
5
|
+
This *acts_as* extension provides the capabilities for sorting and reordering a number of objects in a list.
|
6
|
+
If you do not specify custom position +column+ in the options, a key named +pos+ will be used automatically.
|
7
|
+
|
8
|
+
## Installation
|
9
|
+
|
10
|
+
<code>gem install acts_a_list_mongoid</code>
|
11
|
+
|
12
|
+
## Usage
|
13
|
+
|
14
|
+
See the /specs folder specs that demontrate the API. Usage examples are located in the /examples folder.
|
15
|
+
|
16
|
+
## Example
|
17
|
+
|
18
|
+
<pre>
|
19
|
+
require 'mongoid'
|
20
|
+
require 'mongoid_embedded_helper'
|
21
|
+
|
22
|
+
Mongoid.configure.master = Mongo::Connection.new.db('acts_as_list-test')
|
23
|
+
|
24
|
+
class Item
|
25
|
+
include Mongoid::Document
|
26
|
+
include Mongoid::Timestamps
|
27
|
+
include ActsAsList::Mongoid
|
28
|
+
|
29
|
+
field :pos, :type => Integer
|
30
|
+
field :number, :type => Integer
|
31
|
+
|
32
|
+
acts_as_list :column => :pos
|
33
|
+
|
34
|
+
embedded_in :list, :inverse_of => :items
|
35
|
+
end
|
36
|
+
|
37
|
+
class List
|
38
|
+
include Mongoid::Document
|
39
|
+
field :name, :type => String
|
40
|
+
embeds_many :items
|
41
|
+
end
|
42
|
+
|
43
|
+
|
44
|
+
todo_list = List.new :name => 'My todo list'
|
45
|
+
|
46
|
+
%w{'clean', 'wash', 'repair'}.each do |name|
|
47
|
+
todo_item = Item.new(:name => name)
|
48
|
+
todo_list.items << todo_item
|
49
|
+
end
|
50
|
+
todo_list.items.created! # IMPORTANT!!!
|
51
|
+
|
52
|
+
todo_list.items.first.move_to_bottom
|
53
|
+
todo_list.items.last.move_higher
|
54
|
+
</pre>
|
55
|
+
|
56
|
+
|
57
|
+
## Running the specs
|
58
|
+
|
59
|
+
<code>rspec spec</code>
|
60
|
+
|
61
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "acts_as_list_mongoid"
|
8
|
+
gem.summary = %Q{Gem version of acts_as_list for Mongoid}
|
9
|
+
gem.description = %Q{Make your Mongoid model acts as a list. This acts_as extension provides the capabilities for sorting and reordering a number of objects in a list.
|
10
|
+
The instances that take part in the list should have a +position+ field of type Integer.}
|
11
|
+
gem.email = "kmandrup@gmail.com"
|
12
|
+
gem.homepage = "http://github.com/rails/acts_as_list"
|
13
|
+
gem.authors = ["Kristian Mandrup"]
|
14
|
+
gem.add_dependency "mongoid", ">= 2.0.0.beta7"
|
15
|
+
gem.add_dependency "mongoid_embedded_helper", ">= 0.2.3"
|
16
|
+
# gem.add_development_dependency "yard"
|
17
|
+
end
|
18
|
+
Jeweler::GemcutterTasks.new
|
19
|
+
rescue LoadError
|
20
|
+
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
21
|
+
end
|
22
|
+
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
data/example/example.rb
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'mongoid'
|
2
|
+
require 'mongoid_embedded_helper'
|
3
|
+
|
4
|
+
Mongoid.configure.master = Mongo::Connection.new.db('acts_as_list-test')
|
5
|
+
|
6
|
+
class Item
|
7
|
+
include Mongoid::Document
|
8
|
+
include Mongoid::Timestamps
|
9
|
+
include ActsAsList::Mongoid
|
10
|
+
|
11
|
+
field :pos, :type => Integer
|
12
|
+
field :number, :type => Integer
|
13
|
+
|
14
|
+
acts_as_list :column => :pos
|
15
|
+
|
16
|
+
embedded_in :list, :inverse_of => :items
|
17
|
+
end
|
18
|
+
|
19
|
+
class List
|
20
|
+
include Mongoid::Document
|
21
|
+
field :name, :type => String
|
22
|
+
embeds_many :items
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
todo_list = List.new :name => 'My todo list'
|
27
|
+
|
28
|
+
%w{'clean', 'wash', 'repair'}.each do |name|
|
29
|
+
todo_item = Item.new(:name => name)
|
30
|
+
todo_list.items << todo_item
|
31
|
+
end
|
32
|
+
todo_list.items.created!
|
33
|
+
|
34
|
+
todo_list.items.first.move_to_bottom
|
35
|
+
todo_list.items.last.move_higher
|
data/init.rb
ADDED
data/lib/.DS_Store
ADDED
Binary file
|
data/lib/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'acts_as_list_mongoid'
|
@@ -0,0 +1,370 @@
|
|
1
|
+
require "mongoid"
|
2
|
+
require 'mongoid_embedded_helper'
|
3
|
+
|
4
|
+
module ActsAsList
|
5
|
+
module Mongoid
|
6
|
+
def self.included(model)
|
7
|
+
model.class_eval do
|
8
|
+
extend InitializerMethods
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
module InitializerMethods
|
13
|
+
def acts_as_list(options = {})
|
14
|
+
configuration = { :column => 'position' }
|
15
|
+
configuration.update(options) if options.is_a?(Hash)
|
16
|
+
configuration[:scope] = "#{configuration[:scope]}_id".intern if configuration[:scope].is_a?(Symbol) && configuration[:scope].to_s !~ /_id$/
|
17
|
+
|
18
|
+
# write_inheritable_attribute :acts_as_list_options, configuration
|
19
|
+
# class_inheritable_reader :acts_as_list_options
|
20
|
+
|
21
|
+
define_method :position_column do
|
22
|
+
configuration[:column].to_s
|
23
|
+
end
|
24
|
+
|
25
|
+
if !configuration[:scope]
|
26
|
+
define_method :scope_condition do
|
27
|
+
{position_key.ne => nil}
|
28
|
+
end
|
29
|
+
elsif configuration[:scope].is_a?(Symbol)
|
30
|
+
define_method :scope_condition do
|
31
|
+
{ "#{configuration[:scope].to_s}" => "\#{#{configuration[:scope].to_s}}".to_i }.symbolize_keys!
|
32
|
+
end
|
33
|
+
else
|
34
|
+
raise ArgumentError, "acts_as_list must either take a valid scope option or be in an embedded document and use the parent document as scope"
|
35
|
+
end
|
36
|
+
|
37
|
+
include ::Mongoid::EmbeddedHelper
|
38
|
+
include InstanceMethods
|
39
|
+
include Fields
|
40
|
+
include Triggers
|
41
|
+
extend Fields
|
42
|
+
extend ClassMethods
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
module ClassMethods
|
47
|
+
def in_scope
|
48
|
+
where(scope_condition)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
module InstanceMethods
|
53
|
+
def order_by_position conditions, extras = []
|
54
|
+
sub_collection = in_collection.where(conditions)
|
55
|
+
sub_collection = if embedded?
|
56
|
+
sub_collection.sort { |x,y| x.my_position <=> y.my_position }
|
57
|
+
else
|
58
|
+
sub_collection.order_by([position_key, :desc])
|
59
|
+
end
|
60
|
+
|
61
|
+
if !extras.empty?
|
62
|
+
sub_collection = if embedded?
|
63
|
+
sub_collection.sort do |x,y|
|
64
|
+
if x.my_position == y.my_position
|
65
|
+
x.created_at <=> y.created_at
|
66
|
+
else
|
67
|
+
x.my_position <=> y.my_position
|
68
|
+
end
|
69
|
+
end
|
70
|
+
else
|
71
|
+
sub_collection.order_by(extras)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
sub_collection
|
76
|
+
end
|
77
|
+
|
78
|
+
# conditions, { position_column => 1 }
|
79
|
+
def do_decrement( conditions, options)
|
80
|
+
in_collection.where(conditions).adjust! position_key => -1
|
81
|
+
end
|
82
|
+
|
83
|
+
def do_increment( conditions, options)
|
84
|
+
in_collection.where(conditions).adjust! position_key => 1
|
85
|
+
end
|
86
|
+
|
87
|
+
def less_than_me
|
88
|
+
{ position_key.lt => my_position.to_i}
|
89
|
+
end
|
90
|
+
|
91
|
+
def greater_than_me
|
92
|
+
{ position_key.gt => my_position.to_i}
|
93
|
+
end
|
94
|
+
|
95
|
+
def insert_at(position = 1)
|
96
|
+
insert_in_list_at(position)
|
97
|
+
end
|
98
|
+
|
99
|
+
# Insert the item at the given position (defaults to the top position of 1).
|
100
|
+
def insert_in_list_at(position = 1)
|
101
|
+
insert_at_position(position)
|
102
|
+
end
|
103
|
+
|
104
|
+
# Swap positions with the next lower item, if one exists.
|
105
|
+
def move_lower
|
106
|
+
low_item = lower_item
|
107
|
+
return unless low_item
|
108
|
+
|
109
|
+
low_item.decrement_position
|
110
|
+
increment_position
|
111
|
+
end
|
112
|
+
|
113
|
+
# Swap positions with the next higher item, if one exists.
|
114
|
+
def move_higher
|
115
|
+
high_item = higher_item
|
116
|
+
return unless high_item
|
117
|
+
|
118
|
+
high_item.increment_position
|
119
|
+
decrement_position
|
120
|
+
end
|
121
|
+
|
122
|
+
# Move to the bottom of the list. If the item is already in the list, the items below it have their
|
123
|
+
# position adjusted accordingly.
|
124
|
+
def move_to_bottom
|
125
|
+
return unless in_list?
|
126
|
+
|
127
|
+
decrement_positions_on_lower_items
|
128
|
+
assume_bottom_position
|
129
|
+
end
|
130
|
+
|
131
|
+
# Move to the top of the list. If the item is already in the list, the items above it have their
|
132
|
+
# position adjusted accordingly.
|
133
|
+
def move_to_top
|
134
|
+
return unless in_list?
|
135
|
+
|
136
|
+
increment_positions_on_higher_items
|
137
|
+
assume_top_position
|
138
|
+
end
|
139
|
+
|
140
|
+
# Removes the item from the list.
|
141
|
+
def remove_from_list
|
142
|
+
if in_list?
|
143
|
+
decrement_positions_on_lower_items
|
144
|
+
set_my_position nil
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
# Increase the position of this item without adjusting the rest of the list.
|
149
|
+
def increment_position
|
150
|
+
return unless in_list?
|
151
|
+
# in_collection.where(:pos => my_position).
|
152
|
+
adjust!(position_key => 1)
|
153
|
+
save!
|
154
|
+
end
|
155
|
+
|
156
|
+
# Decrease the position of this item without adjusting the rest of the list.
|
157
|
+
def decrement_position
|
158
|
+
return unless in_list?
|
159
|
+
|
160
|
+
# in_collection.where(:pos => my_position).
|
161
|
+
adjust!(position_key => -1)
|
162
|
+
save!
|
163
|
+
end
|
164
|
+
|
165
|
+
# Return +true+ if this object is the first in the list.
|
166
|
+
def first?
|
167
|
+
return false unless in_list?
|
168
|
+
my_position == 1
|
169
|
+
end
|
170
|
+
|
171
|
+
# Return +true+ if this object is the last in the list.
|
172
|
+
def last?
|
173
|
+
return false unless in_list?
|
174
|
+
bottom_pos = bottom_position_in_list
|
175
|
+
my_position == bottom_pos
|
176
|
+
end
|
177
|
+
|
178
|
+
# Return the next higher item in the list.
|
179
|
+
def higher_item
|
180
|
+
return nil unless in_list?
|
181
|
+
conditions = scope_condition.merge!( less_than_me )
|
182
|
+
|
183
|
+
order_by_position(conditions).last
|
184
|
+
end
|
185
|
+
|
186
|
+
# Return the next lower item in the list.
|
187
|
+
def lower_item
|
188
|
+
return nil unless in_list?
|
189
|
+
|
190
|
+
conditions = scope_condition.merge!( greater_than_me )
|
191
|
+
|
192
|
+
order_by_position(conditions).first
|
193
|
+
end
|
194
|
+
|
195
|
+
# Test if this record is in a list
|
196
|
+
def in_list?
|
197
|
+
!my_position.nil?
|
198
|
+
end
|
199
|
+
|
200
|
+
# sorts all items in the list
|
201
|
+
# if two items have same position, the one created more recently goes first
|
202
|
+
def sort
|
203
|
+
conditions = scope_condition
|
204
|
+
|
205
|
+
list_items = order_by_position(conditions, :created_at.desc).to_a
|
206
|
+
|
207
|
+
list_items.each_with_index do |list_item, index|
|
208
|
+
list_item.set_my_position index + 1
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
private
|
213
|
+
|
214
|
+
def add_to_list_top
|
215
|
+
increment_positions_on_all_items
|
216
|
+
end
|
217
|
+
|
218
|
+
def add_to_list_bottom
|
219
|
+
bottom_pos = bottom_position_in_list.to_i
|
220
|
+
set_my_position(bottom_pos + 1)
|
221
|
+
end
|
222
|
+
|
223
|
+
# Overwrite this method to define the scope of the list changes
|
224
|
+
def scope_condition
|
225
|
+
{}
|
226
|
+
end
|
227
|
+
|
228
|
+
# Returns the bottom position number in the list.
|
229
|
+
# bottom_position_in_list # => 2
|
230
|
+
def bottom_position_in_list(except = nil)
|
231
|
+
item = bottom_item #(except)
|
232
|
+
item ? item.my_position : 0
|
233
|
+
end
|
234
|
+
|
235
|
+
# Returns the bottom item
|
236
|
+
def bottom_item(except = nil)
|
237
|
+
conditions = scope_condition
|
238
|
+
if except
|
239
|
+
conditions.merge!( { position_key.ne => except.my_position } )
|
240
|
+
end
|
241
|
+
|
242
|
+
order_by_position(conditions).last
|
243
|
+
end
|
244
|
+
|
245
|
+
# Forces item to assume the bottom position in the list.
|
246
|
+
def assume_bottom_position
|
247
|
+
pos = bottom_position_in_list(self).to_i + 1
|
248
|
+
set_my_position(pos)
|
249
|
+
end
|
250
|
+
|
251
|
+
# Forces item to assume the top position in the list.
|
252
|
+
def assume_top_position
|
253
|
+
set_my_position(1)
|
254
|
+
end
|
255
|
+
|
256
|
+
# This has the effect of moving all the higher items up one.
|
257
|
+
def decrement_positions_on_higher_items(position)
|
258
|
+
conditions = scope_condition
|
259
|
+
conditions.merge!( { position_key.lt => position } )
|
260
|
+
in_collection.where(conditions).adjust! position_key => 1
|
261
|
+
end
|
262
|
+
|
263
|
+
# This has the effect of moving all the lower items up one.
|
264
|
+
def decrement_positions_on_lower_items
|
265
|
+
return unless in_list?
|
266
|
+
conditions = scope_condition
|
267
|
+
conditions.merge!( greater_than_me )
|
268
|
+
|
269
|
+
decrease_all! in_collection.where(conditions)
|
270
|
+
end
|
271
|
+
|
272
|
+
# This has the effect of moving all the higher items down one.
|
273
|
+
def increment_positions_on_higher_items
|
274
|
+
return unless in_list?
|
275
|
+
conditions = scope_condition
|
276
|
+
conditions.merge!( less_than_me )
|
277
|
+
|
278
|
+
increase_all! in_collection.where(conditions)
|
279
|
+
end
|
280
|
+
|
281
|
+
def adjust_all! collection, number
|
282
|
+
collection.adjust! position_key => number
|
283
|
+
end
|
284
|
+
|
285
|
+
def increase_all! collection
|
286
|
+
adjust_all! collection, 1
|
287
|
+
end
|
288
|
+
|
289
|
+
def decrease_all! collection
|
290
|
+
adjust_all! collection, -1
|
291
|
+
end
|
292
|
+
|
293
|
+
# This has the effect of moving all the lower items down one.
|
294
|
+
def increment_positions_on_lower_items(position)
|
295
|
+
conditions = scope_condition
|
296
|
+
conditions.merge!( { position_key.gte => position } )
|
297
|
+
|
298
|
+
increase_all! in_collection.where(conditions)
|
299
|
+
end
|
300
|
+
|
301
|
+
# Increments position (<tt>position_column</tt>) of all items in the list.
|
302
|
+
def increment_positions_on_all_items
|
303
|
+
conditions = scope_condition
|
304
|
+
|
305
|
+
increase_all! in_collection.where(conditions)
|
306
|
+
end
|
307
|
+
|
308
|
+
def insert_at_position(position)
|
309
|
+
remove_from_list
|
310
|
+
increment_positions_on_lower_items(position)
|
311
|
+
set_my_position(position)
|
312
|
+
end
|
313
|
+
end
|
314
|
+
|
315
|
+
module Triggers
|
316
|
+
def after_parentize
|
317
|
+
# should register on root element to be called when root is saved first time!?
|
318
|
+
end
|
319
|
+
|
320
|
+
def created!
|
321
|
+
self['created_at'] = Time.now
|
322
|
+
self['updated_at'] = Time.now
|
323
|
+
add_to_list_bottom unless in_list?
|
324
|
+
end
|
325
|
+
|
326
|
+
end
|
327
|
+
|
328
|
+
module Fields
|
329
|
+
def my_position
|
330
|
+
self[position_column]
|
331
|
+
end
|
332
|
+
|
333
|
+
def set_my_position new_position
|
334
|
+
if new_position != my_position
|
335
|
+
self[position_column] = new_position
|
336
|
+
save!
|
337
|
+
end
|
338
|
+
end
|
339
|
+
|
340
|
+
def [](field_name)
|
341
|
+
self.send field_name
|
342
|
+
end
|
343
|
+
|
344
|
+
def []=(key, value)
|
345
|
+
if set_allowed?(key)
|
346
|
+
@attributes[key.to_s] = value
|
347
|
+
elsif write_allowed?(key)
|
348
|
+
self.send("#{key}=", value)
|
349
|
+
end
|
350
|
+
save!
|
351
|
+
end
|
352
|
+
|
353
|
+
def ==(other)
|
354
|
+
return true if other.equal?(self)
|
355
|
+
return true if other.instance_of?(self.class) and other._id == self._id
|
356
|
+
false
|
357
|
+
end
|
358
|
+
|
359
|
+
def position_key
|
360
|
+
position_column.to_sym
|
361
|
+
end
|
362
|
+
end
|
363
|
+
end
|
364
|
+
end
|
365
|
+
|
366
|
+
class Array
|
367
|
+
def created!
|
368
|
+
each {|i| i.created! }
|
369
|
+
end
|
370
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
class Item
|
2
|
+
include Mongoid::Document
|
3
|
+
include Mongoid::Timestamps
|
4
|
+
include ActsAsList::Mongoid
|
5
|
+
|
6
|
+
field :pos, :type => Integer
|
7
|
+
field :number, :type => Integer
|
8
|
+
|
9
|
+
acts_as_list :column => :pos
|
10
|
+
|
11
|
+
embedded_in :list, :inverse_of => :items
|
12
|
+
end
|
13
|
+
|
14
|
+
class List
|
15
|
+
include Mongoid::Document
|
16
|
+
field :name, :type => String
|
17
|
+
embeds_many :items
|
18
|
+
end
|
data/spec/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--format nested --color
|
@@ -0,0 +1,104 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../spec_helper')
|
2
|
+
|
3
|
+
require 'acts_as_list_mongoid'
|
4
|
+
require 'embedded_item'
|
5
|
+
|
6
|
+
describe 'ActsAsList for Mongoid' do
|
7
|
+
|
8
|
+
before :each do
|
9
|
+
@list = List.create!
|
10
|
+
@list.items = []
|
11
|
+
(1..4).each do |counter|
|
12
|
+
@list.items << Item.new(:number => counter)
|
13
|
+
end
|
14
|
+
@list.save!
|
15
|
+
|
16
|
+
@list.items.created!
|
17
|
+
end
|
18
|
+
|
19
|
+
after :each do
|
20
|
+
Mongoid.database.collections.each do |coll|
|
21
|
+
coll.remove
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def get_positions list
|
26
|
+
list.items.sort { |x,y| x.my_position <=> y.my_position }.map(&:number)
|
27
|
+
end
|
28
|
+
|
29
|
+
context "4 list items (1,2,3,4) that have parent_id pointing to first list container" do
|
30
|
+
describe '# initial configuration' do
|
31
|
+
it "should list items 1 to 4 in order" do
|
32
|
+
positions = get_positions @list
|
33
|
+
positions.should == [1, 2, 3, 4]
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe '#reordering' do
|
38
|
+
it "should move item 2 to position 3" do
|
39
|
+
@list.items[1].increment_position
|
40
|
+
@list.items[2].decrement_position
|
41
|
+
get_positions(@list).should == [1, 3, 2, 4]
|
42
|
+
end
|
43
|
+
|
44
|
+
|
45
|
+
it "should move item 2 to position 3" do
|
46
|
+
@list.items.where(:number => 2).first.move_lower
|
47
|
+
get_positions(@list).should == [1, 3, 2, 4]
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should move item 2 to position 1" do
|
51
|
+
@list.items.where(:number => 2).first.move_higher
|
52
|
+
get_positions(@list).should == [2, 1, 3, 4]
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should move item 1 to bottom" do
|
56
|
+
@list.items.where(:number => 1).first.move_to_bottom
|
57
|
+
get_positions(@list).should == [2, 3, 4, 1]
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should move item 1 to top" do
|
61
|
+
@list.items.where(:number => 1).first.move_to_top
|
62
|
+
get_positions(@list).should == [1, 2, 3, 4]
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should move item 2 to bottom" do
|
66
|
+
@list.items.where(:number => 2).first.move_to_bottom
|
67
|
+
get_positions(@list).should == [1, 3, 4, 2]
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should move item 4 to top" do
|
71
|
+
@list.items.where(:number => 4).first.move_to_top
|
72
|
+
get_positions(@list).should == [4, 1, 2, 3]
|
73
|
+
end
|
74
|
+
|
75
|
+
it "should move item 3 to bottom" do
|
76
|
+
get_positions(@list).should == [1, 2, 3, 4]
|
77
|
+
|
78
|
+
@list.items.where(:number => 3).first.move_to_bottom
|
79
|
+
get_positions(@list).should == [1, 2, 4, 3]
|
80
|
+
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
describe 'relative position queries' do
|
85
|
+
it "should find item 2 to be lower item of item 1" do
|
86
|
+
expected = @list.items.where(:pos => 2).first
|
87
|
+
@list.items.where(:pos => 1).first.lower_item.should == expected
|
88
|
+
end
|
89
|
+
|
90
|
+
it "should not find any item higher than nr 1" do
|
91
|
+
@list.items.where(:pos => 1).first.higher_item.should == nil
|
92
|
+
end
|
93
|
+
|
94
|
+
it "should find item 3 to be higher item of item 4" do
|
95
|
+
expected = @list.items.where(:pos => 3).first
|
96
|
+
@list.items.where(:pos => 4).first.higher_item.should == expected
|
97
|
+
end
|
98
|
+
|
99
|
+
it "should not find item lower than item 4" do
|
100
|
+
@list.items.where(:pos => 4).first.lower_item.should == nil
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
data/spec/spec.opts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color --format nested
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,111 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: acts_as_list_mongoid
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 1
|
8
|
+
- 0
|
9
|
+
version: 0.1.0
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Kristian Mandrup
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2010-07-06 00:00:00 +02:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: mongoid
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
segments:
|
29
|
+
- 2
|
30
|
+
- 0
|
31
|
+
- 0
|
32
|
+
- beta7
|
33
|
+
version: 2.0.0.beta7
|
34
|
+
type: :runtime
|
35
|
+
version_requirements: *id001
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: mongoid_embedded_helper
|
38
|
+
prerelease: false
|
39
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
40
|
+
none: false
|
41
|
+
requirements:
|
42
|
+
- - ">="
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
segments:
|
45
|
+
- 0
|
46
|
+
- 2
|
47
|
+
- 3
|
48
|
+
version: 0.2.3
|
49
|
+
type: :runtime
|
50
|
+
version_requirements: *id002
|
51
|
+
description: |-
|
52
|
+
Make your Mongoid model acts as a list. This acts_as extension provides the capabilities for sorting and reordering a number of objects in a list.
|
53
|
+
The instances that take part in the list should have a +position+ field of type Integer.
|
54
|
+
email: kmandrup@gmail.com
|
55
|
+
executables: []
|
56
|
+
|
57
|
+
extensions: []
|
58
|
+
|
59
|
+
extra_rdoc_files:
|
60
|
+
- README.markdown
|
61
|
+
files:
|
62
|
+
- .DS_Store
|
63
|
+
- README.markdown
|
64
|
+
- Rakefile
|
65
|
+
- VERSION
|
66
|
+
- example/example.rb
|
67
|
+
- init.rb
|
68
|
+
- lib/.DS_Store
|
69
|
+
- lib/acts_as_list_mongoid.rb
|
70
|
+
- lib/init.rb
|
71
|
+
- lib/mongoid/acts_as_list.rb
|
72
|
+
- model/embedded_item.rb
|
73
|
+
- spec/.rspec
|
74
|
+
- spec/acts_as_list/embedded/custom_embedded_spec.rb
|
75
|
+
- spec/spec.opts
|
76
|
+
- spec/spec_helper.rb
|
77
|
+
has_rdoc: true
|
78
|
+
homepage: http://github.com/rails/acts_as_list
|
79
|
+
licenses: []
|
80
|
+
|
81
|
+
post_install_message:
|
82
|
+
rdoc_options:
|
83
|
+
- --charset=UTF-8
|
84
|
+
require_paths:
|
85
|
+
- lib
|
86
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
87
|
+
none: false
|
88
|
+
requirements:
|
89
|
+
- - ">="
|
90
|
+
- !ruby/object:Gem::Version
|
91
|
+
segments:
|
92
|
+
- 0
|
93
|
+
version: "0"
|
94
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
95
|
+
none: false
|
96
|
+
requirements:
|
97
|
+
- - ">="
|
98
|
+
- !ruby/object:Gem::Version
|
99
|
+
segments:
|
100
|
+
- 0
|
101
|
+
version: "0"
|
102
|
+
requirements: []
|
103
|
+
|
104
|
+
rubyforge_project:
|
105
|
+
rubygems_version: 1.3.7
|
106
|
+
signing_key:
|
107
|
+
specification_version: 3
|
108
|
+
summary: Gem version of acts_as_list for Mongoid
|
109
|
+
test_files:
|
110
|
+
- spec/acts_as_list/embedded/custom_embedded_spec.rb
|
111
|
+
- spec/spec_helper.rb
|