Livery
A simple presenter library for Rails.
Installation
Add this line to your application's Gemfile:
gem 'livery'
Usage
Presenter classes that wrap models should be named
[ModelName]Presenter
, and inherit from Livery::Presenter
.
The underlying model object is called a resource
, and is passed in
initialization. Let's say we have a Post
model:
# app/models/post.rb
class Post < ApplicationRecord
# title: string, body: text
belongs_to :author
end
An empty PostPresenter
would look like:
# app/presenters/post_presenter.rb
class PostPresenter < Livery::Presenter
resource :post
end
By default, no methods are added except resource
and, as an alias,
the name of the resource; in this case post
. So you should define
methods or explicitly delegate them to the underlying object:
# app/presenters/post_presenter.rb
class PostPresenter < Livery::Presenter
resource :post
delegate :title,
:body,
to: :post
def posted_at
if post.created_at.present?
post.created_at.strftime('%a, %b %d %Y')
else
'Not posted yet'
end
end
end
# example:
post = Post.new title: 'An aviation point of view'
post_presenter = PostPresenter.new(post)
post_presenter.title # => 'An aviation point of view'
post_presenter.posted_at # => 'Not posted yet'
Controllers
Livery provides some convenience methods to wrap model objects with presenters, and to ensure that only presenters are passed to the view:
# app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
include Livery::Controller # add this line
end
The use_presenters!
method overrides view_assigns
so that instance
variables are not passed to views. It also defines a present()
method to explicitly pass them:
# app/controllers/posts_controller.rb
class PostsController < ApplicationController
use_presenters!
def show
@post = Post.find(params[:id])
present(current_post: @post)
end
end
present
will find the PostPresenter
class to wrap the @post
model object, and assign it to the @current_post
instance variable
in the view:
# app/views/posts/show.html.erb:
<h1><%= @current_post.title ></h1>
<h2>Posted at <%= @current_post.posted_at %></h2>
Presenter associations
Given an associated model (post.author
) with a presenter class:
class AuthorPresenter < Livery::Presenter
resource :author
def full_name
.given_name + ' ' + .surname
end
end
you can use presenter_association
:
class PostPresenter < Livery::Presenter
resource :post
presenter_association :author
# ...
end
PostPresenter.new(post)..full_name # => "Amelia Earhart"
Development
Run bin/rake spec
to run the tests.
To install this gem onto your local machine, run bundle exec rake install
.
To release a new version, update the version number in version.rb
,
and then run bundle exec rake release
, which will create a git tag
for the version, push git commits and tags, and push the .gem
file
to rubygems.org.