Giter Site home page Giter Site logo

yap's Introduction

Yet another paginator for Ruby on Rails, which adds a paginate scope to your ActiveRecords.

Setup

Include Yap into your models to add the paginate scope like so:

class User < ActiveRecord::Base
  include Yap
  belongs_to :team
end
Defaults (optional)

To setup default parameters call Yap.configure. You can access the defaults as block parameter. Call this somewhere in config/initializers/.

Yap.configure do |defaults|
  defaults.page = 1
  defaults.per_page = 10
  defaults.sort = 'id'
  defaults.direction = 'ASC'
  defaults.disable_warnings = false
end

The above settings will be applied if you do not set your own.

Custom Naming (optional)

ActiveRecords can implement the method map_name_to_column to define aliases for columns. This can be useful to hide internal naming from users and to make sorting by associations possible (more on this below).

COLUMN_MAP = {
    'team' => 'teams.name',
    'birthday' => 'date_of_birth'
}
def self.map_name_to_column(name)
  return COLUMN_MAP[name]
end

Usage

Basics

Assuming you included Yap into User, you can now do something like this:

User.paginate
# => Page 1 with default order and size

User.paginate(
    page:       1,
    per_page:   10,
    sort:       'id',
    direction:  'ASC'
)
# => Invocation with custom options.

User.paginate(params).last_page
# => Last page as a number for the previously paginated query
User.paginate(params).range
# => E.g. { from: 1, to: 10, total: 100 }
User.paginate(params).total
# => total number of results for this filters

User.paginate(params).without_pagination do |rel|
  # access rel without limit and offset; filters still apply
  rel.count
end
# => total number of results

User.paginate(
  sort: {
    'gender'        => 'desc',
    'date_of_birth' => 'asc'
  }
)
# => Sort by gender and date_of_birth (method 1)

User.paginate(sort: 'gender,date_of_birth', direction: 'desc,asc')
# => Sort by gender and date_of_birth (method 2)

User.filter('gender' => 'f')
# => All female users

User.filter(
    'team_id' => '1,2',
    'gender' => 'm'
)
# => All males of teams 1 and 2

User.filter(
    # Note that '0...3' means [0,1,2] while '0..3' means [0,1,2,3]
    'date_of_birth' => '1990-01-01...1991-01-01'
)
# => All users born in 1990

User.filter('team_id' => '!null')
# => All users with any team

User.paginate(
    page:   1,
    filter: { 'team' => 'null' }
)
# => Combining filter and pagination

User.paginate(params)
# => Passing parameters in controller (http://localhost/users?filter[gender]=f)

Yap will convert strings to symbols or numbers and vice versa where necessary. This make the last one a really powerful method of offering the pagination API directly to the user.

Chaining

The paginate scope can be chained with other ActiveRecord methods like joins, where etc..

Advanced

The "team" alias defined in the column map above allows us to sort the results by the name of the team a user belongs to. "teams.name" describes the "teams" table and the "name" column in our database. We need to join the team association to make this work. Example:

User.joins(:team).paginate(sort: 'team')

Error Handling

If an option cannot be parsed it will raise Yap::PaginationError or Yap::FilterError, which are both Yap::YapErrors. I suggest to use rescue_from in the controller to handle such a case.

rescue_from Yap::YapError, with: :handle_yap_error

def handle_yap_error
  # generate user friendly error here, set flash[:error] or whatever you like.
end

Full Example

require 'yap'

class User < ActiveRecord::Base
  include Yap
  belongs_to :team

  COLUMN_MAP = {
      'team' => 'teams.name',
      'birthday' => 'date_of_birth'
  }
  def self.map_name_to_column(name)
    return COLUMN_MAP[name]
  end
end

class UsersController < ApplicationController
  rescue_from Yap::YapError, with: :handle_yap_error

  def handle_yap_error
    # generate user friendly error here, set flash[:error] or whatever you like.
  end

  def index
    respond_with User.joins(:team).paginate(params)
  end
end

Changelog

1.2

  • added sorting by multiple elements
    • method 1: ?sort[team]=desc&sort[date_of_birth]=asc
    • method 2: ?sort=team,date_of_birth&direction=desc,asc
      • missing directions will fall back to default

1.1

  • changed default behavior for range to not include total; saves time when using range
    • call range(true) to include total value

1.0

  • changed last_page to base on the actual query not only the parameters
    • this now produces correct results if there are custom where conditions
  • added range method which can be used like last_page
    • provides a hash containing the limits of the latest queried page
  • added total method to get the total number of results
  • added without_pagination which takes a block an serves an Activerecord::Relation which is not paginated

yap's People

Contributors

amshaegar13 avatar

Watchers

 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.