mm_sortable_item 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +4 -0
- data/.rspec +2 -0
- data/.rvmrc +1 -0
- data/Gemfile +4 -0
- data/README.md +36 -0
- data/Rakefile +1 -0
- data/lib/mm_sortable_item.rb +111 -0
- data/lib/mm_sortable_item/version.rb +3 -0
- data/mm_sortable_item.gemspec +25 -0
- data/spec/fabricators/sortable_helper_fabricator.rb +7 -0
- data/spec/mm_sortable_item_spec.rb +196 -0
- data/spec/spec_helper.rb +42 -0
- metadata +113 -0
data/.gitignore
ADDED
data/.rspec
ADDED
data/.rvmrc
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
rvm use --create 1.9.2@mm_sortable_item_gem
|
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
# mm\_sortable\_item
|
2
|
+
|
3
|
+
This is a quick little MongoMapper plugin that provides some basic acts-as-list style functionality on mongo documents. By default things are added to the list bottom.
|
4
|
+
|
5
|
+
## Usage
|
6
|
+
|
7
|
+
In the gemfile:
|
8
|
+
|
9
|
+
gem 'mm_sortable_item'
|
10
|
+
|
11
|
+
In your model:
|
12
|
+
|
13
|
+
``` ruby
|
14
|
+
class SortableDocument
|
15
|
+
include MongoMapper::Document
|
16
|
+
plugin MongoMapper::Plugins::SortableItem
|
17
|
+
|
18
|
+
list_scope_column :parent_id # optional if you want to scope the lists
|
19
|
+
|
20
|
+
# ...
|
21
|
+
end
|
22
|
+
```
|
23
|
+
|
24
|
+
Then you have access to some helpful methods, such as:
|
25
|
+
|
26
|
+
* `.in_order` retrieves the list items in order
|
27
|
+
* `.in_list(id)` retrieves the items scoped as you wish
|
28
|
+
* `.reorder(orderd_array_of_ids)` sets the positions of the given ids in order
|
29
|
+
* `object.set_position(position)` inserts object into the list at the given position
|
30
|
+
|
31
|
+
## Credit
|
32
|
+
|
33
|
+
John Nunemaker for mongo_mapper itself, as well as a start down the road of how to implement this. It's definitely not as "fully functional" as `acts_as_list`, but it does everything I need :).
|
34
|
+
|
35
|
+
* Author: Matt Wilson (mwilson@agoragames.com)
|
36
|
+
* GitHub: http://github.com/hypomodern
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'bundler/gem_tasks'
|
@@ -0,0 +1,111 @@
|
|
1
|
+
require "mm_sortable_item/version"
|
2
|
+
require "mongo_mapper"
|
3
|
+
|
4
|
+
# An ActsAsList-ish plugin for MongoMapper, since this doesn't seem to exist in a well-tested form.
|
5
|
+
# Props to John Nunemaker for starting us down the right path here
|
6
|
+
module MongoMapper
|
7
|
+
module Plugins
|
8
|
+
module SortableItem
|
9
|
+
extend ActiveSupport::Concern
|
10
|
+
|
11
|
+
included do
|
12
|
+
key :position, Integer
|
13
|
+
scope :in_order, sort(:position)
|
14
|
+
class_attribute :sortable_item_options
|
15
|
+
self.sortable_item_options = { :list_scope => nil }
|
16
|
+
|
17
|
+
# some callbacks we'll want
|
18
|
+
before_create :add_to_list_bottom, :unless => :in_list?
|
19
|
+
before_destroy :decrement_positions_on_lower_items
|
20
|
+
end
|
21
|
+
|
22
|
+
module ClassMethods
|
23
|
+
def reorder(ids)
|
24
|
+
ids.each_with_index do |id, index|
|
25
|
+
set(id, :position => index + 1)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def in_list list_id = nil
|
30
|
+
where(conditions_for_list_scope(list_id))
|
31
|
+
end
|
32
|
+
|
33
|
+
def conditions_for_list_scope list_id
|
34
|
+
the_query = {}
|
35
|
+
the_column = list_scope_column
|
36
|
+
if the_column
|
37
|
+
the_query = { the_column => list_id }
|
38
|
+
end
|
39
|
+
the_query
|
40
|
+
end
|
41
|
+
|
42
|
+
def list_scope_column= new_column
|
43
|
+
self.sortable_item_options[:list_scope] = new_column
|
44
|
+
end
|
45
|
+
|
46
|
+
def list_scope_column
|
47
|
+
self.sortable_item_options[:list_scope]
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
module InstanceMethods
|
52
|
+
def in_list?
|
53
|
+
!send(:position).nil?
|
54
|
+
end
|
55
|
+
|
56
|
+
def scoped_list_id
|
57
|
+
the_column = self.class.list_scope_column
|
58
|
+
the_column ? self.send(the_column) : nil
|
59
|
+
end
|
60
|
+
|
61
|
+
def add_to_list_bottom
|
62
|
+
add_to_list
|
63
|
+
end
|
64
|
+
|
65
|
+
def add_to_list_top
|
66
|
+
add_to_list 1
|
67
|
+
end
|
68
|
+
|
69
|
+
def add_to_list position = bottom_of_list
|
70
|
+
remove_from_list
|
71
|
+
increment_positions_on_lower_items position
|
72
|
+
set_position position
|
73
|
+
end
|
74
|
+
|
75
|
+
def bottom_of_list
|
76
|
+
self.class.in_list( scoped_list_id ).count + 1
|
77
|
+
end
|
78
|
+
|
79
|
+
def lower_than_conditions position = self.position
|
80
|
+
query = self.class.conditions_for_list_scope scoped_list_id
|
81
|
+
query.merge( :position.gte => position )
|
82
|
+
end
|
83
|
+
|
84
|
+
def decrement_positions_on_lower_items position = self.position
|
85
|
+
self.class.decrement( lower_than_conditions(position), { :position => 1 } )
|
86
|
+
end
|
87
|
+
|
88
|
+
def increment_positions_on_lower_items position = self.position
|
89
|
+
self.class.increment( lower_than_conditions(position), { :position => 1 } )
|
90
|
+
end
|
91
|
+
|
92
|
+
def remove_from_list
|
93
|
+
if in_list?
|
94
|
+
decrement_positions_on_lower_items
|
95
|
+
self.position = nil
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def set_position new_position
|
100
|
+
remove_from_list
|
101
|
+
increment_positions_on_lower_items new_position
|
102
|
+
if new_position != self.position
|
103
|
+
self.position = new_position
|
104
|
+
save unless new_record?
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "mm_sortable_item/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "mm_sortable_item"
|
7
|
+
s.version = MmSortableItem::VERSION
|
8
|
+
s.authors = ["Matt Wilson"]
|
9
|
+
s.email = ["mhw@hypomodern.com"]
|
10
|
+
s.homepage = "https://github.com/agoragames/mm_sortable_item"
|
11
|
+
s.summary = "Tiny MongoMapper plugin for treating a collection as a list"
|
12
|
+
s.description = "Tiny MongoMapper plugin for treating a collection as a list"
|
13
|
+
|
14
|
+
s.rubyforge_project = "mm_sortable_item"
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
|
21
|
+
s.add_runtime_dependency('mongo_mapper')
|
22
|
+
s.add_development_dependency('rspec')
|
23
|
+
s.add_development_dependency('fabrication')
|
24
|
+
s.add_development_dependency('database_cleaner')
|
25
|
+
end
|
@@ -0,0 +1,196 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module MongoMapper::Plugins
|
4
|
+
describe SortableItem do
|
5
|
+
after do
|
6
|
+
SortableHelper.sortable_item_options = { :list_scope => nil }
|
7
|
+
end
|
8
|
+
|
9
|
+
describe "plugin .included magic" do
|
10
|
+
it "sets a new mongo key of :position on the document" do
|
11
|
+
the_position_key = SortableHelper.keys["position"]
|
12
|
+
the_position_key.should_not be_nil
|
13
|
+
|
14
|
+
the_position_key.type.should == Integer
|
15
|
+
end
|
16
|
+
it "provides a new scope named .in_order" do
|
17
|
+
SortableHelper.scopes.keys.should include(:in_order)
|
18
|
+
end
|
19
|
+
it "sets up a class_accessor called .sortable_item_options" do
|
20
|
+
SortableHelper.sortable_item_options.should == { :list_scope => nil }
|
21
|
+
end
|
22
|
+
|
23
|
+
describe "default callbacks" do
|
24
|
+
it "sets up a before_create callback to ensure the item gets added to the list" do
|
25
|
+
the_callbacks = SortableHelper._create_callbacks
|
26
|
+
the_callbacks.find { |cb| cb.kind == :before && cb.filter == :add_to_list_bottom }.
|
27
|
+
should_not be_nil
|
28
|
+
end
|
29
|
+
it "adds new items to the bottom of the list by default" do
|
30
|
+
3.times { Fabricate(:sortable_helper) }
|
31
|
+
new_item = Fabricate(:sortable_helper)
|
32
|
+
new_item.position.should == 4
|
33
|
+
end
|
34
|
+
context "with already-ordered items" do
|
35
|
+
it "doesn't change the position" do
|
36
|
+
(1..3).to_a.each { |i| Fabricate(:sortable_helper, :position => i + 1) }
|
37
|
+
new_item = Fabricate(:sortable_helper, :position => 1)
|
38
|
+
new_item.reload
|
39
|
+
new_item.position.should == 1
|
40
|
+
SortableHelper.in_order.first.should == new_item
|
41
|
+
end
|
42
|
+
end
|
43
|
+
it "sets up a before_destroy callback to ensure the item gets removed from the list" do
|
44
|
+
the_callbacks = SortableHelper._destroy_callbacks
|
45
|
+
the_callbacks.find { |cb| cb.kind == :before && cb.filter == :decrement_positions_on_lower_items }.
|
46
|
+
should_not be_nil
|
47
|
+
end
|
48
|
+
it "gracefully removes an item from the list, leaving it in proper order on destroy" do
|
49
|
+
(1..3).to_a.each { |i| Fabricate(:sortable_helper, :position => i) }
|
50
|
+
SortableHelper.in_order.first.destroy
|
51
|
+
SortableHelper.in_order.all.map { |sh| sh.position }.should == [1, 2]
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
describe ".list_scope_column=" do
|
57
|
+
it "allows you to give it a column name that will be saved into the options" do
|
58
|
+
SortableHelper.list_scope_column = :list_scope_id
|
59
|
+
SortableHelper.sortable_item_options.should == { :list_scope => :list_scope_id }
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
describe ".list_scope_column" do
|
64
|
+
it "returns the defined list_scope_column" do
|
65
|
+
SortableHelper.list_scope_column = :list_scope_id
|
66
|
+
SortableHelper.list_scope_column.should == :list_scope_id
|
67
|
+
end
|
68
|
+
it "returns nil by default" do
|
69
|
+
SortableHelper.list_scope_column.should be_nil
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
describe ".in_list" do
|
74
|
+
it "returns a scope that... uh, scopes the list" do
|
75
|
+
SortableHelper.in_list.should be_a_kind_of(Plucky::Query)
|
76
|
+
end
|
77
|
+
it "filters nothing by default (entire collection is the list)" do
|
78
|
+
3.times { Fabricate(:sortable_helper) }
|
79
|
+
recs = SortableHelper.in_list.in_order.all
|
80
|
+
recs.size.should == 3
|
81
|
+
end
|
82
|
+
it "uses the :list_scope option to build the scope" do
|
83
|
+
SortableHelper.list_scope_column = :list_scope_id
|
84
|
+
SortableHelper.should_receive(:where).with({:list_scope_id => 3})
|
85
|
+
SortableHelper.in_list(3)
|
86
|
+
end
|
87
|
+
it "correctly scopes the list, baby" do
|
88
|
+
5.times { Fabricate(:sortable_helper, :list_scope_id => 1) }
|
89
|
+
5.times { Fabricate(:sortable_helper, :list_scope_id => 2) }
|
90
|
+
SortableHelper.list_scope_column = :list_scope_id
|
91
|
+
|
92
|
+
SortableHelper.in_list(1).count.should == 5
|
93
|
+
SortableHelper.in_list(2).count.should == 5
|
94
|
+
SortableHelper.count.should == 10
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
describe ".reorder" do
|
99
|
+
it "updates the positions of the given ids based on their array order" do
|
100
|
+
items = (1..3).to_a.map { |i| Fabricate(:sortable_helper, :position => i) }
|
101
|
+
|
102
|
+
SortableHelper.reorder([items[2].id, items[0].id, items[1].id])
|
103
|
+
new_list = SortableHelper.in_list.in_order.all
|
104
|
+
new_list[0].should == items[2]
|
105
|
+
new_list[1].should == items[0]
|
106
|
+
new_list[2].should == items[1]
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
describe "#in_list?" do
|
111
|
+
it "returns false if the record doesn't have a numeric position" do
|
112
|
+
sortable = Fabricate.build(:sortable_helper)
|
113
|
+
sortable.stub!(:position).and_return(nil)
|
114
|
+
sortable.position.should be_nil
|
115
|
+
sortable.should_not be_in_list
|
116
|
+
end
|
117
|
+
it "returns true if the record has a numeric position" do
|
118
|
+
sortable = Fabricate.build(:sortable_helper)
|
119
|
+
sortable.position = 1
|
120
|
+
sortable.should be_in_list
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
describe "#scoped_list_id" do
|
125
|
+
it "returns nil if there is no defined list scope" do
|
126
|
+
Fabricate.build(:sortable_helper).scoped_list_id.should be_nil
|
127
|
+
end
|
128
|
+
it "returns the value of the given column" do
|
129
|
+
SortableHelper.list_scope_column = :list_scope_id
|
130
|
+
sortable = Fabricate.build(:sortable_helper)
|
131
|
+
sortable.scoped_list_id.should == sortable.list_scope_id
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
describe "#bottom_of_list" do
|
136
|
+
before do
|
137
|
+
SortableHelper.list_scope_column = :list_scope_id
|
138
|
+
5.times { Fabricate(:sortable_helper, :list_scope_id => 1) }
|
139
|
+
2.times { Fabricate(:sortable_helper, :list_scope_id => 2) }
|
140
|
+
end
|
141
|
+
it "returns the position that an item at the bottom of the list should have" do
|
142
|
+
list_1 = Fabricate.build(:sortable_helper, :list_scope_id => 1)
|
143
|
+
list_2 = Fabricate.build(:sortable_helper, :list_scope_id => 2)
|
144
|
+
list_1.bottom_of_list.should == 6
|
145
|
+
list_2.bottom_of_list.should == 3
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
describe "#remove_from_list" do
|
150
|
+
before do
|
151
|
+
@list = (1..5).to_a.map { |i| Fabricate(:sortable_helper, :name => "Item #{i}") }
|
152
|
+
@middle_item = @list[2]
|
153
|
+
end
|
154
|
+
it "sets the current position to nil" do
|
155
|
+
@middle_item.remove_from_list
|
156
|
+
@middle_item.position.should be_nil
|
157
|
+
end
|
158
|
+
it "pushes everything below the current item up a notch" do
|
159
|
+
old_position = @middle_item.position
|
160
|
+
@middle_item.remove_from_list
|
161
|
+
item_3 = @list[3]
|
162
|
+
item_3.reload
|
163
|
+
item_3.position.should == old_position
|
164
|
+
|
165
|
+
item_4 = @list[4]
|
166
|
+
item_4.reload
|
167
|
+
item_4.position.should == old_position + 1
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
describe "#set_position" do
|
172
|
+
it "sets the item to the new position" do
|
173
|
+
item = Fabricate.build(:sortable_helper)
|
174
|
+
item.set_position 5
|
175
|
+
item.position.should == 5
|
176
|
+
end
|
177
|
+
it "moves everything below the given position down a notch" do
|
178
|
+
list = (1..5).to_a.map { |i| Fabricate(:sortable_helper, :name => "Item #{i}") }
|
179
|
+
item = Fabricate(:sortable_helper)
|
180
|
+
item.set_position 3
|
181
|
+
old_item_3 = SortableHelper.find(list[2].id)
|
182
|
+
old_item_3.reload
|
183
|
+
old_item_3.position.should == 4
|
184
|
+
end
|
185
|
+
it "inserts it correctly into the list" do
|
186
|
+
list = (1..5).to_a.map { |i| Fabricate(:sortable_helper, :name => "Item #{i}") }
|
187
|
+
item = Fabricate(:sortable_helper, :name => "The New Guy")
|
188
|
+
item.set_position 3
|
189
|
+
new_list = SortableHelper.in_list.in_order.all
|
190
|
+
new_list[2].should == item
|
191
|
+
new_list.map { |i| i.name + ": pos = " + i.position.to_s }.should == ["Item 1: pos = 1", "Item 2: pos = 2", "The New Guy: pos = 3", "Item 3: pos = 4", "Item 4: pos = 5", "Item 5: pos = 6"]
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
end
|
196
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
2
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
3
|
+
|
4
|
+
require 'rubygems'
|
5
|
+
require 'bundler'
|
6
|
+
Bundler.setup
|
7
|
+
require 'rspec'
|
8
|
+
require 'fabrication'
|
9
|
+
require 'database_cleaner'
|
10
|
+
|
11
|
+
|
12
|
+
require 'mm_sortable_item'
|
13
|
+
|
14
|
+
MongoMapper.database = 'mm_sortable_item_spec'
|
15
|
+
|
16
|
+
class SortableHelper
|
17
|
+
include MongoMapper::Document
|
18
|
+
plugin MongoMapper::Plugins::SortableItem
|
19
|
+
|
20
|
+
key :name, String
|
21
|
+
key :list_scope_id, Integer
|
22
|
+
end
|
23
|
+
|
24
|
+
SortableHelper.collection.remove
|
25
|
+
|
26
|
+
RSpec.configure do |config|
|
27
|
+
config.mock_with :rspec
|
28
|
+
|
29
|
+
config.before(:suite) do
|
30
|
+
DatabaseCleaner.strategy = :truncation
|
31
|
+
DatabaseCleaner.clean_with(:truncation)
|
32
|
+
end
|
33
|
+
|
34
|
+
config.before(:each) do
|
35
|
+
DatabaseCleaner.start
|
36
|
+
DatabaseCleaner.clean
|
37
|
+
end
|
38
|
+
|
39
|
+
config.after(:each) do
|
40
|
+
DatabaseCleaner.clean
|
41
|
+
end
|
42
|
+
end
|
metadata
ADDED
@@ -0,0 +1,113 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: mm_sortable_item
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: 0.0.1
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Matt Wilson
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
|
13
|
+
date: 2011-07-31 00:00:00 -04:00
|
14
|
+
default_executable:
|
15
|
+
dependencies:
|
16
|
+
- !ruby/object:Gem::Dependency
|
17
|
+
name: mongo_mapper
|
18
|
+
prerelease: false
|
19
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
20
|
+
none: false
|
21
|
+
requirements:
|
22
|
+
- - ">="
|
23
|
+
- !ruby/object:Gem::Version
|
24
|
+
version: "0"
|
25
|
+
type: :runtime
|
26
|
+
version_requirements: *id001
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rspec
|
29
|
+
prerelease: false
|
30
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
31
|
+
none: false
|
32
|
+
requirements:
|
33
|
+
- - ">="
|
34
|
+
- !ruby/object:Gem::Version
|
35
|
+
version: "0"
|
36
|
+
type: :development
|
37
|
+
version_requirements: *id002
|
38
|
+
- !ruby/object:Gem::Dependency
|
39
|
+
name: fabrication
|
40
|
+
prerelease: false
|
41
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
42
|
+
none: false
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: "0"
|
47
|
+
type: :development
|
48
|
+
version_requirements: *id003
|
49
|
+
- !ruby/object:Gem::Dependency
|
50
|
+
name: database_cleaner
|
51
|
+
prerelease: false
|
52
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
53
|
+
none: false
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: "0"
|
58
|
+
type: :development
|
59
|
+
version_requirements: *id004
|
60
|
+
description: Tiny MongoMapper plugin for treating a collection as a list
|
61
|
+
email:
|
62
|
+
- mhw@hypomodern.com
|
63
|
+
executables: []
|
64
|
+
|
65
|
+
extensions: []
|
66
|
+
|
67
|
+
extra_rdoc_files: []
|
68
|
+
|
69
|
+
files:
|
70
|
+
- .gitignore
|
71
|
+
- .rspec
|
72
|
+
- .rvmrc
|
73
|
+
- Gemfile
|
74
|
+
- README.md
|
75
|
+
- Rakefile
|
76
|
+
- lib/mm_sortable_item.rb
|
77
|
+
- lib/mm_sortable_item/version.rb
|
78
|
+
- mm_sortable_item.gemspec
|
79
|
+
- spec/fabricators/sortable_helper_fabricator.rb
|
80
|
+
- spec/mm_sortable_item_spec.rb
|
81
|
+
- spec/spec_helper.rb
|
82
|
+
has_rdoc: true
|
83
|
+
homepage: https://github.com/agoragames/mm_sortable_item
|
84
|
+
licenses: []
|
85
|
+
|
86
|
+
post_install_message:
|
87
|
+
rdoc_options: []
|
88
|
+
|
89
|
+
require_paths:
|
90
|
+
- lib
|
91
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
92
|
+
none: false
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: "0"
|
97
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
98
|
+
none: false
|
99
|
+
requirements:
|
100
|
+
- - ">="
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: "0"
|
103
|
+
requirements: []
|
104
|
+
|
105
|
+
rubyforge_project: mm_sortable_item
|
106
|
+
rubygems_version: 1.6.2
|
107
|
+
signing_key:
|
108
|
+
specification_version: 3
|
109
|
+
summary: Tiny MongoMapper plugin for treating a collection as a list
|
110
|
+
test_files:
|
111
|
+
- spec/fabricators/sortable_helper_fabricator.rb
|
112
|
+
- spec/mm_sortable_item_spec.rb
|
113
|
+
- spec/spec_helper.rb
|