ranked-model 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 ADDED
@@ -0,0 +1,3 @@
1
+ pkg/*
2
+ *.gem
3
+ .bundle
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format documentation
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in ranked-model.gemspec
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,81 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ ranked-model (0.0.1)
5
+ activerecord (>= 3.0.3)
6
+
7
+ GEM
8
+ remote: http://rubygems.org/
9
+ specs:
10
+ abstract (1.0.0)
11
+ actionpack (3.0.3)
12
+ activemodel (= 3.0.3)
13
+ activesupport (= 3.0.3)
14
+ builder (~> 2.1.2)
15
+ erubis (~> 2.6.6)
16
+ i18n (~> 0.4)
17
+ rack (~> 1.2.1)
18
+ rack-mount (~> 0.6.13)
19
+ rack-test (~> 0.5.6)
20
+ tzinfo (~> 0.3.23)
21
+ activemodel (3.0.3)
22
+ activesupport (= 3.0.3)
23
+ builder (~> 2.1.2)
24
+ i18n (~> 0.4)
25
+ activerecord (3.0.3)
26
+ activemodel (= 3.0.3)
27
+ activesupport (= 3.0.3)
28
+ arel (~> 2.0.2)
29
+ tzinfo (~> 0.3.23)
30
+ activesupport (3.0.3)
31
+ arel (2.0.7)
32
+ builder (2.1.2)
33
+ diff-lcs (1.1.2)
34
+ erubis (2.6.6)
35
+ abstract (>= 1.0.0)
36
+ genspec (0.1.1)
37
+ rspec
38
+ sc-core-ext (>= 1.2.0)
39
+ i18n (0.5.0)
40
+ mocha (0.9.10)
41
+ rake
42
+ rack (1.2.1)
43
+ rack-mount (0.6.13)
44
+ rack (>= 1.0.0)
45
+ rack-test (0.5.7)
46
+ rack (>= 1.0)
47
+ railties (3.0.3)
48
+ actionpack (= 3.0.3)
49
+ activesupport (= 3.0.3)
50
+ rake (>= 0.8.7)
51
+ thor (~> 0.14.4)
52
+ rake (0.8.7)
53
+ rspec (2.4.0)
54
+ rspec-core (~> 2.4.0)
55
+ rspec-expectations (~> 2.4.0)
56
+ rspec-mocks (~> 2.4.0)
57
+ rspec-core (2.4.0)
58
+ rspec-expectations (2.4.0)
59
+ diff-lcs (~> 1.1.2)
60
+ rspec-mocks (2.4.0)
61
+ rspec-rails (2.4.1)
62
+ actionpack (~> 3.0)
63
+ activesupport (~> 3.0)
64
+ railties (~> 3.0)
65
+ rspec (~> 2.4.0)
66
+ sc-core-ext (1.2.1)
67
+ activesupport (>= 2.3.5)
68
+ sqlite3 (1.3.3)
69
+ thor (0.14.6)
70
+ tzinfo (0.3.24)
71
+
72
+ PLATFORMS
73
+ ruby
74
+
75
+ DEPENDENCIES
76
+ genspec
77
+ mocha
78
+ ranked-model!
79
+ rspec
80
+ rspec-rails
81
+ sqlite3
data/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2011 Iridesco LLC (support@harvestapp.com)
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,7 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ require 'rspec/core/rake_task'
5
+ RSpec::Core::RakeTask.new('spec')
6
+
7
+ task :default => :spec
data/Readme.mkd ADDED
@@ -0,0 +1,98 @@
1
+ **ranked-model** is a modern row sorting library built for Rails 3. It uses ARel aggressivly and is better optimized than most other libraries.
2
+
3
+ Installation
4
+ ------------
5
+
6
+ To install ranked-model, just add it to your `Gemfile`:
7
+
8
+ gem 'ranked-model'
9
+
10
+ # Or pin ranked-model to git
11
+ # gem 'ranked-model',
12
+ # :git => 'git@github.com:harvesthq/ranked-model.git'
13
+
14
+ Then use `bundle install` to update your `Gemfile.lock`.
15
+
16
+ Simple Use
17
+ ----------
18
+
19
+ Use of ranked-model is straight ahead. Get some ducks:
20
+
21
+ class Duck < ActiveRecord::Base
22
+ end
23
+
24
+ Put your ducks in a row:
25
+
26
+ class Duck < ActiveRecord::Base
27
+
28
+ include RankedModel
29
+ ranks :row_order
30
+
31
+ end
32
+
33
+ This simple example assumes an integer column called `row_order`. To order Ducks by this order:
34
+
35
+ Duck.rank(:row_order).all
36
+
37
+ The ranking integers stored in the `raw_order` column will be big and spaced apart. When you
38
+ implement a sorting UI, just update the resource with the position instead:
39
+
40
+ @duck.update_attribute :row_order_position, 0 # or 1, 2, 37. :first and :last are also valid
41
+
42
+ So using a normal json controller where `@duck.attributes = params[:duck]; @duck.save`, JS can
43
+ look pretty elegant:
44
+
45
+ $.ajax({
46
+ type: 'PUT',
47
+ url: '/ducks',
48
+ dataType: 'json',
49
+ data: { duck: { row_order_position: 0 } }, // or whatever your new position is
50
+ });
51
+
52
+ Complex Use
53
+ -----------
54
+
55
+ The `ranks` method takes serveral arguments:
56
+
57
+ class Duck < ActiveRecord::Base
58
+
59
+ include RankedModel
60
+
61
+ ranks :row_order, # Name this ranker, used with rank()
62
+ :column => :sort_order # Override the default column, which defaults to the name
63
+
64
+ belongs_to :pond
65
+ ranks :swimming_order,
66
+ :with_same => :pond_id # Ducks belong_to Ponds, make the ranker scoped to one pond
67
+
68
+ scope :walking, where(:walking => true )
69
+ ranks :walking_order,
70
+ :scope => :walking # Narrow this ranker to a scope
71
+
72
+ end
73
+
74
+ When you make a query, add the rank:
75
+
76
+ Duck.rank(:row_order)
77
+
78
+ Pond.first.ducks.rank(:swimming_order)
79
+
80
+ Duck.walking.rank(:walking)
81
+
82
+ Internals
83
+ ---------
84
+
85
+ This libarary is written using ARel from the ground-up. This leaves the code much cleaner
86
+ than many implementations. ranked-model is also optimized to write to the database as little
87
+ as possible: ranks are stored as a number between 0 and 65534 (just below MEDIUMINT in MySQL).
88
+ When an item is given a new position, it assigns itself a rank number between two neighbors.
89
+ This allows several movements of items before no digits are available between to neighbors. When
90
+ this occurs, ranked-model will rebalance the distribution of rank numbers across all memebers
91
+ of the ranked group.
92
+
93
+ Contributing
94
+ ------------
95
+
96
+ Fork, clone, write a test, write some code, commit, push, send a pull request. Github FTW!
97
+
98
+ This project was open-sourced by [Harvest](http://getharvest.com/). [We're hiring!](http://www.getharvest.com/careers)
@@ -0,0 +1,53 @@
1
+ require File.dirname(__FILE__)+'/ranked-model/ranker'
2
+ require File.dirname(__FILE__)+'/ranked-model/railtie' if defined?(Rails::Railtie)
3
+
4
+ module RankedModel
5
+
6
+ # Signed MEDIUMINT in MySQL
7
+ #
8
+ MAX_RANK_VALUE = 65534
9
+
10
+ def self.included base
11
+
12
+ base.class_eval do
13
+ cattr_accessor :rankers
14
+
15
+ extend RankedModel::ClassMethods
16
+
17
+ before_save :handle_ranking
18
+
19
+ scope :rank, lambda { |name|
20
+ order arel_table[ ranker(name.to_sym).column ]
21
+ }
22
+ end
23
+
24
+ end
25
+
26
+ private
27
+
28
+ def handle_ranking
29
+ self.class.rankers.each do |ranker|
30
+ ranker.with(self).handle_ranking
31
+ end
32
+ end
33
+
34
+ module ClassMethods
35
+
36
+ def ranker name
37
+ rankers.find do |ranker|
38
+ ranker.name == name
39
+ end
40
+ end
41
+
42
+ private
43
+
44
+ def ranks *args
45
+ self.rankers ||= []
46
+ ranker = RankedModel::Ranker.new(*args)
47
+ self.rankers << ranker
48
+ attr_accessor "#{ranker.name}_position"
49
+ end
50
+
51
+ end
52
+
53
+ end
@@ -0,0 +1,14 @@
1
+ require 'ranked-model'
2
+ require 'rails'
3
+
4
+ module RankedModel
5
+
6
+ class Railtie < Rails::Railtie
7
+
8
+ initializer "ranked-model.initialize" do |app|
9
+
10
+ end
11
+
12
+ end
13
+
14
+ end
@@ -0,0 +1,153 @@
1
+ module RankedModel
2
+
3
+ class Ranker
4
+ attr_accessor :name, :column, :scope, :with_same
5
+
6
+ def initialize name, options={}
7
+ self.name = name.to_sym
8
+ self.column = options[:column] || name
9
+
10
+ [ :scope, :with_same ].each do |key|
11
+ self.send "#{key}=", options[key]
12
+ end
13
+ end
14
+
15
+ def with instance
16
+ Mapper.new self, instance
17
+ end
18
+
19
+ class Mapper
20
+ attr_accessor :ranker, :instance
21
+
22
+ def initialize ranker, instance
23
+ self.ranker = ranker
24
+ self.instance = instance
25
+ end
26
+
27
+ def handle_ranking
28
+ update_index_from_position
29
+ assure_unique_position
30
+ end
31
+
32
+ def update_rank! value
33
+ # Bypass callbacks
34
+ #
35
+ instance.class.where(:id => instance.id).update_all ["#{ranker.column} = ?", value]
36
+ end
37
+
38
+ def position
39
+ instance.send "#{ranker.name}_position"
40
+ end
41
+
42
+ def rank
43
+ instance.send "#{ranker.column}"
44
+ end
45
+
46
+ private
47
+
48
+ def position_at value
49
+ instance.send "#{ranker.name}_position=", value
50
+ update_index_from_position
51
+ end
52
+
53
+ def rank_at value
54
+ instance.send "#{ranker.column}=", value
55
+ end
56
+
57
+ def rank_changed?
58
+ instance.send "#{ranker.column}_changed?"
59
+ end
60
+
61
+ def new_record?
62
+ instance.new_record?
63
+ end
64
+
65
+ def update_index_from_position
66
+ case position
67
+ when :first
68
+ if !current_order.empty? && current_order.first.rank
69
+ rank_at( current_order.first.rank / 2 )
70
+ else
71
+ rank_at 0
72
+ end
73
+ when :last
74
+ if !current_order.empty? && current_order.last.rank
75
+ rank_at( ( RankedModel::MAX_RANK_VALUE + current_order.last.rank ) / 2 )
76
+ else
77
+ rank_at RankedModel::MAX_RANK_VALUE
78
+ end
79
+ when String
80
+ position_at position.to_i
81
+ when 0
82
+ position_at :first
83
+ when Integer
84
+ if current_order[position]
85
+ rank_at( ( current_order[position-1].rank + current_order[position].rank ) / 2 )
86
+ else
87
+ position_at :last
88
+ end
89
+ end
90
+ end
91
+
92
+ def assure_unique_position
93
+ if ( new_record? || rank_changed? )
94
+ unless rank
95
+ rank_at RankedModel::MAX_RANK_VALUE
96
+ end
97
+
98
+ if (rank > RankedModel::MAX_RANK_VALUE) || (current_order.find do |rankable|
99
+ rankable.rank.nil? ||
100
+ rankable.rank == rank
101
+ end)
102
+ rebalance_ranks
103
+ end
104
+ end
105
+ end
106
+
107
+ def rebalance_ranks
108
+ total = current_order.size + 2
109
+ has_set_self = false
110
+ total.times do |index|
111
+ next if index == 0 || index == total
112
+ rank_value = RankedModel::MAX_RANK_VALUE / total * index
113
+ index = index - 1
114
+ if has_set_self
115
+ index = index - 1
116
+ else
117
+ if !current_order[index] ||
118
+ ( !current_order[index].rank.nil? &&
119
+ current_order[index].rank >= rank )
120
+ rank_at rank_value
121
+ has_set_self = true
122
+ next
123
+ end
124
+ end
125
+ current_order[index].update_rank! rank_value
126
+ end
127
+ end
128
+
129
+ def current_order
130
+ @current_order ||= begin
131
+ finder = instance.class
132
+ if ranker.scope
133
+ finder = finder.send ranker.scope
134
+ end
135
+ if ranker.with_same
136
+ finder = finder.where \
137
+ instance.class.arel_table[ranker.with_same].eq(instance.attributes["#{ranker.with_same}"])
138
+ end
139
+ if !new_record?
140
+ finder = finder.where \
141
+ instance.class.arel_table[:id].not_eq(instance.id)
142
+ end
143
+ finder.order(ranker.column).select([:id, ranker.column]).collect { |ordered_instance|
144
+ RankedModel::Ranker::Mapper.new ranker, ordered_instance
145
+ }
146
+ end
147
+ end
148
+
149
+ end
150
+
151
+ end
152
+
153
+ end
@@ -0,0 +1,3 @@
1
+ module RankedModel
2
+ VERSION = "0.0.1"
3
+ end
data/rails/init.rb ADDED
@@ -0,0 +1 @@
1
+ require 'ranked-model/railtie'
@@ -0,0 +1,28 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "ranked-model/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "ranked-model"
7
+ s.version = RankedModel::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Matthew Beale"]
10
+ s.email = ["matt.beale@madhatted.com"]
11
+ s.homepage = "https://github.com/harvesthq/ranked-model"
12
+ s.summary = %q{An acts_as_sortable replacement built for Rails 3}
13
+ s.description = %q{ranked-model is a modern row sorting library built for Rails 3. It uses ARel aggressivly and is better optimized than most other libraries.}
14
+
15
+ s.add_dependency "activerecord", ">= 3.0.3"
16
+ s.add_development_dependency "rspec"
17
+ s.add_development_dependency "rspec-rails"
18
+ s.add_development_dependency "sqlite3"
19
+ s.add_development_dependency "genspec"
20
+ s.add_development_dependency "mocha"
21
+
22
+ # s.rubyforge_project = "ranked-model"
23
+
24
+ s.files = `git ls-files`.split("\n")
25
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
26
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
27
+ s.require_paths = ["lib"]
28
+ end
@@ -0,0 +1,127 @@
1
+ require 'spec_helper'
2
+
3
+ describe Duck do
4
+
5
+ before {
6
+ @ducks = {
7
+ :quacky => Duck.create(
8
+ :name => 'Quacky',
9
+ :pond => 'Shin' ),
10
+ :feathers => Duck.create(
11
+ :name => 'Feathers',
12
+ :pond => 'Shin' ),
13
+ :wingy => Duck.create(
14
+ :name => 'Wingy',
15
+ :pond => 'Shin' ),
16
+ :webby => Duck.create(
17
+ :name => 'Webby',
18
+ :pond => 'Boyden' ),
19
+ :waddly => Duck.create(
20
+ :name => 'Waddly',
21
+ :pond => 'Meddybemps' ),
22
+ :beaky => Duck.create(
23
+ :name => 'Beaky',
24
+ :pond => 'Great Moose' )
25
+ }
26
+ @ducks.each { |name, duck|
27
+ duck.reload
28
+ duck.row_position = 0
29
+ duck.size_position = 0
30
+ duck.age_position = 0
31
+ duck.save!
32
+ }
33
+ @ducks.each {|name, duck| duck.reload }
34
+ }
35
+
36
+ describe "sorting by size on in_shin_pond" do
37
+
38
+ before {
39
+ @ducks[:quacky].update_attribute :size_position, 0
40
+ @ducks[:wingy].update_attribute :size_position, 2
41
+ }
42
+
43
+ subject { Duck.in_shin_pond.rank(:size).all }
44
+
45
+ its(:size) { should == 3 }
46
+
47
+ its(:first) { should == @ducks[:quacky] }
48
+
49
+ its(:last) { should == @ducks[:wingy] }
50
+
51
+ end
52
+
53
+ describe "sorting by age on Shin pond" do
54
+
55
+ before {
56
+ @ducks[:feathers].update_attribute :age_position, 0
57
+ @ducks[:wingy].update_attribute :age_position, 0
58
+ }
59
+
60
+ subject { Duck.where(:pond => 'Shin').rank(:age).all }
61
+
62
+ its(:size) { should == 3 }
63
+
64
+ its(:first) { should == @ducks[:wingy] }
65
+
66
+ its(:last) { should == @ducks[:quacky] }
67
+
68
+ end
69
+
70
+ describe "sorting by row" do
71
+
72
+ before {
73
+ @ducks[:beaky].update_attribute :row_position, 0
74
+ @ducks[:webby].update_attribute :row_position, 2
75
+ @ducks[:waddly].update_attribute :row_position, 2
76
+ @ducks[:wingy].update_attribute :row_position, 6
77
+ }
78
+
79
+ subject { Duck.rank(:row).all }
80
+
81
+ its(:size) { should == 6 }
82
+
83
+ its(:first) { should == @ducks[:beaky] }
84
+
85
+ its(:last) { should == @ducks[:wingy] }
86
+
87
+ end
88
+
89
+ describe "mixed sorting by" do
90
+
91
+ before {
92
+ @ducks[:quacky].update_attribute :size_position, 0
93
+ @ducks[:beaky].update_attribute :row_position, 0
94
+ @ducks[:webby].update_attribute :row_position, 2
95
+ @ducks[:wingy].update_attribute :size_position, 1
96
+ @ducks[:waddly].update_attribute :row_position, 2
97
+ @ducks[:wingy].update_attribute :row_position, 6
98
+ @ducks[:webby].update_attribute :row_position, 6
99
+ }
100
+
101
+ describe "row" do
102
+
103
+ subject { Duck.rank(:row).all }
104
+
105
+ its(:size) { should == 6 }
106
+
107
+ its(:first) { should == @ducks[:beaky] }
108
+
109
+ its(:last) { should == @ducks[:webby] }
110
+
111
+ end
112
+
113
+ describe "row" do
114
+
115
+ subject { Duck.in_shin_pond.rank(:size).all }
116
+
117
+ its(:size) { should == 3 }
118
+
119
+ its(:first) { should == @ducks[:quacky] }
120
+
121
+ its(:last) { should == @ducks[:feathers] }
122
+
123
+ end
124
+
125
+ end
126
+
127
+ end
@@ -0,0 +1,18 @@
1
+ require 'spec_helper'
2
+
3
+ describe RankedModel::Ranker, 'initialized' do
4
+
5
+ subject {
6
+ RankedModel::Ranker.new \
7
+ :overview,
8
+ :column => :a_sorting_column,
9
+ :scope => :a_scope,
10
+ :with_same => :a_column
11
+ }
12
+
13
+ its(:name) { should == :overview }
14
+ its(:column) { should == :a_sorting_column }
15
+ its(:scope) { should == :a_scope }
16
+ its(:with_same) { should == :a_column }
17
+
18
+ end
@@ -0,0 +1,7 @@
1
+ require 'spec_helper'
2
+
3
+ describe RankedModel do
4
+
5
+ it { should define_constant(:VERSION) }
6
+
7
+ end
@@ -0,0 +1,15 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+
4
+ require 'ranked-model' # and any other gems you need
5
+
6
+ Dir[File.join(File.dirname(__FILE__), 'support/**/*.rb')].each {|f| require f}
7
+
8
+ RSpec.configure do |config|
9
+ config.mock_with :mocha
10
+ config.use_transactional_fixtures = true
11
+ end
12
+
13
+ RSpec::Matchers.define :define_constant do |expected|
14
+ match { |actual| actual.const_defined?(expected) }
15
+ end
@@ -0,0 +1,32 @@
1
+ require 'active_record'
2
+ require 'sqlite3'
3
+ require 'logger'
4
+ require 'rspec/rails/adapters'
5
+ require 'rspec/rails/fixture_support'
6
+
7
+ ROOT = File.join(File.dirname(__FILE__), '..')
8
+
9
+ ActiveRecord::Base.logger = Logger.new('tmp/ar_debug.log')
10
+ ActiveRecord::Base.configurations = YAML::load(IO.read('spec/support/database.yml'))
11
+ ActiveRecord::Base.establish_connection('development')
12
+
13
+ ActiveRecord::Schema.define :version => 0 do
14
+ create_table :ducks, :force => true do |t|
15
+ t.string :name
16
+ t.integer :row
17
+ t.integer :size
18
+ t.integer :age
19
+ t.string :pond
20
+ end
21
+ end
22
+
23
+ class Duck < ActiveRecord::Base
24
+
25
+ include RankedModel
26
+ ranks :row
27
+ ranks :size, :scope => :in_shin_pond
28
+ ranks :age, :with_same => :pond
29
+
30
+ scope :in_shin_pond, where(:pond => 'Shin')
31
+
32
+ end
@@ -0,0 +1,5 @@
1
+ development:
2
+ adapter: sqlite3
3
+ database: tmp/data.sqlite3
4
+ pool: 5
5
+ timeout: 5000
metadata ADDED
@@ -0,0 +1,177 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ranked-model
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Matthew Beale
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-02-08 00:00:00 -05:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: activerecord
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 1
30
+ segments:
31
+ - 3
32
+ - 0
33
+ - 3
34
+ version: 3.0.3
35
+ type: :runtime
36
+ version_requirements: *id001
37
+ - !ruby/object:Gem::Dependency
38
+ name: rspec
39
+ prerelease: false
40
+ requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ hash: 3
46
+ segments:
47
+ - 0
48
+ version: "0"
49
+ type: :development
50
+ version_requirements: *id002
51
+ - !ruby/object:Gem::Dependency
52
+ name: rspec-rails
53
+ prerelease: false
54
+ requirement: &id003 !ruby/object:Gem::Requirement
55
+ none: false
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ hash: 3
60
+ segments:
61
+ - 0
62
+ version: "0"
63
+ type: :development
64
+ version_requirements: *id003
65
+ - !ruby/object:Gem::Dependency
66
+ name: sqlite3
67
+ prerelease: false
68
+ requirement: &id004 !ruby/object:Gem::Requirement
69
+ none: false
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ hash: 3
74
+ segments:
75
+ - 0
76
+ version: "0"
77
+ type: :development
78
+ version_requirements: *id004
79
+ - !ruby/object:Gem::Dependency
80
+ name: genspec
81
+ prerelease: false
82
+ requirement: &id005 !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ">="
86
+ - !ruby/object:Gem::Version
87
+ hash: 3
88
+ segments:
89
+ - 0
90
+ version: "0"
91
+ type: :development
92
+ version_requirements: *id005
93
+ - !ruby/object:Gem::Dependency
94
+ name: mocha
95
+ prerelease: false
96
+ requirement: &id006 !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ">="
100
+ - !ruby/object:Gem::Version
101
+ hash: 3
102
+ segments:
103
+ - 0
104
+ version: "0"
105
+ type: :development
106
+ version_requirements: *id006
107
+ description: ranked-model is a modern row sorting library built for Rails 3. It uses ARel aggressivly and is better optimized than most other libraries.
108
+ email:
109
+ - matt.beale@madhatted.com
110
+ executables: []
111
+
112
+ extensions: []
113
+
114
+ extra_rdoc_files: []
115
+
116
+ files:
117
+ - .gitignore
118
+ - .rspec
119
+ - Gemfile
120
+ - Gemfile.lock
121
+ - LICENSE
122
+ - Rakefile
123
+ - Readme.mkd
124
+ - lib/ranked-model.rb
125
+ - lib/ranked-model/railtie.rb
126
+ - lib/ranked-model/ranker.rb
127
+ - lib/ranked-model/version.rb
128
+ - rails/init.rb
129
+ - ranked-model.gemspec
130
+ - spec/duck-model/duck_spec.rb
131
+ - spec/ranked-model/ranker_spec.rb
132
+ - spec/ranked-model/version_spec.rb
133
+ - spec/spec_helper.rb
134
+ - spec/support/active_record.rb
135
+ - spec/support/database.yml
136
+ - tmp/.gitignore
137
+ has_rdoc: true
138
+ homepage: https://github.com/harvesthq/ranked-model
139
+ licenses: []
140
+
141
+ post_install_message:
142
+ rdoc_options: []
143
+
144
+ require_paths:
145
+ - lib
146
+ required_ruby_version: !ruby/object:Gem::Requirement
147
+ none: false
148
+ requirements:
149
+ - - ">="
150
+ - !ruby/object:Gem::Version
151
+ hash: 3
152
+ segments:
153
+ - 0
154
+ version: "0"
155
+ required_rubygems_version: !ruby/object:Gem::Requirement
156
+ none: false
157
+ requirements:
158
+ - - ">="
159
+ - !ruby/object:Gem::Version
160
+ hash: 3
161
+ segments:
162
+ - 0
163
+ version: "0"
164
+ requirements: []
165
+
166
+ rubyforge_project:
167
+ rubygems_version: 1.5.0
168
+ signing_key:
169
+ specification_version: 3
170
+ summary: An acts_as_sortable replacement built for Rails 3
171
+ test_files:
172
+ - spec/duck-model/duck_spec.rb
173
+ - spec/ranked-model/ranker_spec.rb
174
+ - spec/ranked-model/version_spec.rb
175
+ - spec/spec_helper.rb
176
+ - spec/support/active_record.rb
177
+ - spec/support/database.yml