paraphrase
paraphrase provides a way to map one or multiple request params to model scopes.
paraphrase was designed and geared towards building a query-based public API where you may want to require certain parameters to prevent consumers from scraping all your information or to mitigate the possibility of large, performance-intensive data-dumps.
Installation
Via a gemfile:
gem 'paraphrase'
$ bundle
Or manually:
$ gem install paraphrase
Usage
paraphrase aims to be as flexible as possible for your needs.
- From within an
ActiveRecord::Base
subclass:
class Post < ActiveRecord::Base
register_mapping do
scope :by_user, :key => :author
end
def self.by_user()
joins(:user).where(:user => { :name => })
end
end
- In an initializer to register multiple mappings in one place:
# config/initializers/paraphrase.rb
Paraphrase.configure do |mappings|
mappings.register :post do
paraphrases Post
scope :by_user, :key => :author
end
end
- By creating a subclass of
Paraphrase::Query
:
class PostQuery < Paraphrase::Query
paraphrases Post
scope :by_user, :key => :author
end
Then in a controller you can use it in any of the following ways:
class PostsController < ApplicationController
respond_to :html, :json
def index
# Filters out relevant attributes
# and applies scopes relevant to each
# parameter
@posts = Post.paraphrase(params)
# Or
# @posts = Paraphrase.query(:post, params)
# If you created a subclass
# @posts = PostQuery.new(params)
respond_with(@posts)
end
end
In any of these contexts, the :key
option of the :scope
method registers
attribute(s) to extract from the params supplied and what scope to pass them
to. An array of keys can be supplied to pass multiple attributes to a scope.
class Post < ActiveRecord::Base
register_mapping do
scope :by_user, :key => [:first_name, :last_name]
end
def self.by_user(name)
joins(:user).where(:user => { :name => name })
end
end
If a key is required, pass :require => true
to the options. This will
return an empty results set if value for that key is missing.
class Post < ActiveRecord::Base
register_mapping do
scope :by_author, :key => :author, :require => true
scope :published_after, :key => :pub_date
end
end
Post.paraphrase(:pub_date => '2010-10-30') # => []
Plans
- Enable requiring a subset of a compound key.
scope :by_author, :key => [:first_name, :last_name], :require => :first_name
- Support nested hashes in params.
scope :by_author, :key => { :author => [:first_name, :last_name] }