mm_sortable_item 0.0.1
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/.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
|