roar-contrib
Collection of useful Roar contributions and extensions. I just released a pre-release as I would like to know what you all think. Cheers!
Installation
Add this line to your application's Gemfile:
gem 'roar-contrib'
And then execute:
$ bundle
Or install it yourself as:
$ gem install roar-contrib
Representers
Collections with Decorators
When using Decorators, include Roar::Contrib::Decorator::CollectionRepresenter
to create a Representer for a collection of resources.
class SongRepresenter < Roar::Decorator
include Roar::JSON
property :name
end
class SongsRepresenter < Roar::Decorator
include Roar::JSON
include Roar::Contrib::Decorator::CollectionRepresenter
end
This will create a collection (songs
in this case) based on the name of the Representer, using the singular representer (SongRepresenter) to serialize each individual resource in the collection. Therefore, a GET request to /songs
would give you:
{
"songs": [
{
"name": "Thriller"
},
{
"name": "One More Time"
},
{
"name": "Good Vibrations"
}
]
}
If you need more custom behavior and want to define your own collection, you can do it like so:
class SongsRepresenter < Roar::Decorator
include Roar::JSON
collection :top_songs,
:exec_context => :decorator,
:decorator => TopSong
def top_songs
represented
end
end
Pagination with Decorators
Roar-contrib pagination works with either will_paginate or Kaminari. It is based on Nick Sutterer's blog post. You must install one of these for roar-contrib pagination to work. In your Gemfile, include either
gem 'will_paginate'
or
gem 'kaminari'
To paginate, include Roar::Contrib::Decorator::PageRepresenter
and define page_url
in the paginated Representer like so:
class SongRepresenter < Roar::Decorator
include Roar::JSON
property :name
end
class SongsRepresenter < Roar::Decorator
include Roar::JSON
include Roar::Contrib::Decorator::PageRepresenter
collection :songs,
:exec_context => :decorator,
:decorator => SongRepresenter
def songs
represented
end
# If using roar-rails, url helpers are also available here
def page_url(args)
"http://www.roar-contrib.com/songs?#{args.to_query}"
end
end
As you may have guessed, you can combine the CollectionRepresenter
and PageRepresenter
to DRY up the example above. Woot Woot! :stuck_out_tongue_closed_eyes: :boom:
class SongRepresenter < Roar::Decorator
include Roar::JSON
property :name
end
class SongsRepresenter < Roar::Decorator
include Roar::JSON
include Roar::Contrib::Decorator::PageRepresenter
include Roar::Contrib::Decorator::CollectionRepresenter
def page_url(args)
"http://www.roar-contrib.com/songs?#{args.to_query}"
end
end
If you are using Rails, your controller(s) may look like the following...
# Using will_paginate
class SongsController < ActionController::Base
include Roar::Rails::ControllerAdditions
represents :json, Song
def index
@songs = Song.paginate :page => params[:page], :per_page => params[:per_page]
respond_with @songs
end
end
# Using Kaminari
class SongsController < ActionController::Base
include Roar::Rails::ControllerAdditions
represents :json, Song
def index
@songs = Song.page(params[:page]).per params[:per_page]
respond_with @songs
end
end
Now, a GET request to /songs?page=3&per_page=1
would give you:
{
"total_entries": 3,
"links": [
{
"rel": "self",
"href": "http://www.roar-contrib.com/songs?page=3&per_page=1"
},
{
"rel": "previous",
"href": "http://www.roar-contrib.com/songs?page=2&per_page=1"
}
],
"songs": [
{
"name": "Good Vibrations"
}
]
}
You can define additional pagination properties in your response such as per_page
provided by will_paginate, or limit_value
provided by Kaminari, by defining the property in your paginated representer.
class SongsRepresenter < Roar::Decorator
include Roar::JSON
include Roar::Contrib::Decorator::PageRepresenter
include Roar::Contrib::Decorator::CollectionRepresenter
property :per_page # Only works with will_paginate
def page_url(args)
songs_url args
end
end
Roar-contrib provides you with the following methods defined on the Decorator instance that work with either will_paginate
or Kaminari
:
#current_page
#next_page
#previous_page
#per_page
#total_entries
You can use them as properties by telling Roar to execute the methods in the context of the Decorator.
class SongsRepresenter < Roar::Decorator
include Roar::JSON
include Roar::Contrib::Decorator::PageRepresenter
include Roar::Contrib::Decorator::CollectionRepresenter
property :per_page, :exec_context => :decorator # Works with either will_paginate or Kaminari
def page_url(args)
songs_url args
end
end
Contributing
Contributions welcome!! :smile:
- Fork it ( https://github.com/sweatshirtio/roar-contrib/fork )
- Create your feature branch (
git checkout -b my-new-feature
) - Commit your changes (
git commit -am 'Add some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create a new Pull Request