Deli
Tasty URL Parameters for Rails.
Usage
Install
gem install deli
Wire up the controller
class UsersController < ApplicationController
queries :users do
match :created_at
match :status
match :name
end
end
Request Something
/users?created_at=2010..2011&status=active&sort=created_at-,name+&page=2&limit=20
Paginate
You can paginate ActiveRecord and Mongoid models the same way.
def index
@users = User.paginate(self.deli)
@users.total_count
@users.page_count
@users.current_page
# ...
@users.where(:status => "active").each do |user|
# it's scoped
end
end
More coming on this part.
Make your own Sandwich
Perform complex queries on your ActiveRecord/Mongoid models from the URL. Done with the ActiveRecord one, still trying to find the best/right ways to to text and OR queries in mongo with Mongoid.
/users?created_at=2010..2011&status=active&sort=created_at-,name+&page=2&limit=20
...becomes
{
:conditions => [
{:namespace => "users", :key => "created_at", :operators => [">="], :value => "2010"},
{:namespace => "users", :key => "created_at", :operators => ["<="], :value => "2011"},
{:namespace => "users", :key => "status", :operators => ["="], :value => "active"}
],
:order => [
{:namespace => "users", :key => "created_at", :operator => "-"},
{:namespace => "users", :key => "name", :operator => "+"}
],
:offset => 20,
:limit => 20
}
...which in ActiveRecord looks like:
{
:conditions => ["users.created_at >= ? AND users.created_at <= ? AND users.status = ?", Time.zone.parse("2010"), Time.zone.parse("2011"), "active"],
:order => "users.created_at DESC, users.name ASC",
:offset => 20,
:limit => 20
}
...and in Mongoid like this:
{
:created_at => {"$gte" => Time.zone.parse("2010"), "$lte" => Time.zone.parse("2011")}, :status => "active"},
:order => [[:created_at, :desc], [:name, :asc]],
:offset => 20,
:limit => 20
}
There's a ton more you can do with it.
Parameter Types
Deli took ruby-ish conventions for structuring query parameters. Below is how you can write them for each supported attribute type. These conventions aim to be human-readable, so I have avoided using things like "double quotes" because they're escaped to %22 which is not human readable.
Also, you'll have to use javascript to format the query parameters like this, because this is overly complicated for the basic user. But it makes our lives easy, you can write the query straight in the url no problem. And with some simple javascript, the end-user's life is way easier as well.
String
# one word
title=Hello
# multiple individual words (tokens)
title=Hello+World
# exact match (single quotes)
title='Hello+World'
# include "Hello", exclude "World"
title=Hello+-World
# same, for exact matches
title=ruby+-'ruby+on+rails'
# match beginning (match phone, not iphone)
title=^phone
# match end (match ip, like in ip address, not iphone)
title=ip$
# OR or ,
title=jquery+OR+'ruby+on+rails'
title=javascript,ruby
# mix and match them all
title=javascript+-jquery+OR+'ruby+on+rails'+OR+git$
Define in the controller whether you want these to be `exact`. This will make a SQL `=` or `!=` instead of `LIKE` and `NOT LIKE`.
Number
# positive
score=10
# negative
score=-10
# multiple
score=10,-10
# range
score=10..100
# multiple ranges
score=10..100,1000..1500
# range with no start
score=n..100
# range with no end
score=100..n
# mix and match ranges and values
score=1,10,100,1000..n
Dates/Times
# single
start_date=2011-03-12
# multiple
start_date=2011-02-01,2011-03-01
# range
start_date=2011-02-01..2011-03-01
# multiple ranges
start_date=2010-02-01..2010-03-01,2011-02-01..2011-03-01
# range with no start
start_date=t..2011-03-01
# range with no end
start_date=2011-02-01..t
# mix and match ranges and values
start_date=2011-01-01,2011-02-01..2011-03-01
# times (can do all of the above, just add @)
created_at=2011-01-01
Pagination/Limits
page=12&limit=20
Sorting
# ascending
sort=created_at
sort=created_at+
# descending
sort=created_at-
# combine
sort=name,created_at-
Reasons
When you get to coding a table, you want something plug-n-chug with searching, sorting, and pagination. This is either will_paginate or some Javascript Ajax grid plugin. Those get you up and running quickly, but they're impossible to really customize.
MIT License. © 2011 Lance Pollard.