Giter VIP home page Giter VIP logo

ranked-model's Introduction

ranked-model is a modern row sorting library built for Rails 3 & 4. It uses ARel aggressively and is better optimized than most other libraries.

Build Status

Installation

ranked-model passes specs with Rails 3.1, 3.2, 4.0, and 4.1-beta for MySQL, Postgres, and SQLite on Ruby 1.9.2, 1.9.3, 2.0, 2.1, jruby-19mode, and rubinius where Rails supports the platform. This is with the exception of Postgres before Rails 4.0 on all platforms, which is unsupported (I'd gladly accept a PR to fix this).

TL;DR, if you are using Rails 4 and up you are 100% good to go. Before Rails 4, be wary of Postgres.

To install ranked-model, just add it to your Gemfile:

gem 'ranked-model'

# Or pin ranked-model to git
# gem 'ranked-model',
#   :git => '[email protected]:mixonic/ranked-model.git'

Then use bundle install to update your Gemfile.lock.

Simple Use

Use of ranked-model is straight ahead. Get some ducks:

class Duck < ActiveRecord::Base
end

Put your ducks in a row:

class Duck < ActiveRecord::Base

  include RankedModel
  ranks :row_order

end

This simple example assumes an integer column called row_order. To order Ducks by this order:

Duck.rank(:row_order).all

The ranking integers stored in the row_order column will be big and spaced apart. When you implement a sorting UI, just update the resource by appending the column name with _position and indicating the desired position:

@duck.update_attribute :row_order_position, 0  # or 1, 2, 37. :first, :last, :up and :down are also valid

Position numbers begin at zero. A position number greater than the number of records acts the same as :last. :up and :down move the record up/down the ladder by one step.

So using a normal json controller where @duck.attributes = params[:duck]; @duck.save, JS can look pretty elegant:

$.ajax({
  type: 'PUT',
  url: '/ducks',
  dataType: 'json',
  data: { duck: { row_order_position: 0 } },  // or whatever your new position is
});

Complex Use

The ranks method takes serveral arguments:

class Duck < ActiveRecord::Base

  include RankedModel

  ranks :row_order,           # Name this ranker, used with rank()
    :column => :sort_order    # Override the default column, which defaults to the name
  
  belongs_to :pond
  ranks :swimming_order,
    :with_same => :pond_id    # Ducks belong_to Ponds, make the ranker scoped to one pond
  
  scope :walking, where(:walking => true )
  ranks :walking_order,
    :scope => :walking        # Narrow this ranker to a scope

end

When you make a query, add the rank:

Duck.rank(:row_order)

Pond.first.ducks.rank(:swimming_order)

Duck.walking.rank(:walking)

Single Table Inheritance (STI)

ranked-model scopes your records' positions based on the class name of the object. If you have a STI type column set in your model, ranked-model will reference that class for positioning.

Consider this example:

class Vehicle < ActiveRecord::Base
  ranks :row_order
end

class Car < Vehicle
end

class Truck < Vehicle
end

car = Car.create!
truck = Truck.create!

car.row_order
=> 0
truck.row_order
=> 0

In this example, the row_order for both car and truck will be set to 0 because they have different class names (Car and Truck, respectively).

If you would like for both car and truck to be ranked together based on the base Vehicle class instead, use the class_name option:

class Vehicle < ActiveRecord::Base
  ranks :row_order, class_name: 'Vehicle'
end

class Car < Vehicle
end

class Truck < Vehicle
end

car = Car.create!
truck = Truck.create!

car.row_order
=> 0
truck.row_order
=> 4194304

Internals

This library is written using ARel from the ground-up. This leaves the code much cleaner than many implementations. ranked-model is also optimized to write to the database as little as possible: ranks are stored as a number between -8388607 and 8388607 (the MEDIUMINT range in MySQL). When an item is given a new position, it assigns itself a rank number between two neighbors. This allows several movements of items before no digits are available between two neighbors. When this occurs, ranked-model will try to shift other records out of the way. If items can't be easily shifted anymore, it will rebalance the distribution of rank numbers across all members of the ranked group.

Contributing

Fork, clone, write a test, write some code, commit, push, send a pull request. Github FTW!

The specs can be run with sqlite, postgres, and mysql:

DB=postgres bundle exec rake

Is no DB is specified, the tests run against sqlite.

RankedModel is mostly the handiwork of Matthew Beale:

A hearty thanks to these contributors:

ranked-model's People

Contributors

mixonic avatar jguyon avatar andrewradev avatar jamesalmond avatar vinbarnes avatar petergoldstein avatar willnathan avatar alainpilon avatar chrisdpeters avatar jaredbeck avatar kakra avatar vjt avatar mjonuschat avatar pehrlich avatar robotex82 avatar rociiu avatar reu avatar mjc-gh avatar

Watchers

John Lin avatar James Cloos avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.