ArchPresenter
ArchPresenter is a simple, lightweight gem that implements the Presenter pattern.
It allows you to slim down your models and controllers by extracting the logic related to class presentation. You can learn more about this pattern on the Jay Fields' blog.
Installation
Add this line to your application's Gemfile:
gem 'arch_presenter'And then run:
$ bundle
Usage
Super-quick example
Simple, skinny model:
# app/models/user.rb
class User
def first_name
'John'
end
def last_name
'Smith'
end
def title
'Mr.'
end
def name_visible?
true
end
endPresentation logic moved to the presenter:
# app/presenters/user_presenter.rb
class UserPresenter < ArchPresenter::Base
def display_name
if name_visible?
[title, first_name, last_name].join(' ')
else
'(Name hidden)'
end
end
endPresenting the object in the controller:
# app/controllers/users_cotroller.rb
class UsersController < ApplicationController
def show
@user = User.find(params[:id])
@user = present(@user)
end
endUsing the display_name function:
# app/views/users/show.html.erb
<h1><%=@user.display_name %> - User profile</h1>Creating presenter classes
First you will need to create a class that will be used to decorate your object.
Presenter class files should be placed in app/presenters/ and should inherit from ArchPresenter::Base.
Autoloading
You might wish to add app/presenters/ to your autoload path. This will allow rails to automatically detect changes made to the presenter files without the need to restart the server.
In config/application.rb add:
config.autoload_paths << Rails.root.join('app', 'presenters')Decorating
ArchPresenter gem provides a #present function that can be invoked in your controller (or in your view if you preffer decorating your classes there).
To decorate your class use the #present function.
In the controller:
user = User.find(1)
@user = present(user)or in the view:
<body>
<% @user = present(@user) %>
Hello <%= @user.full_name %>!
</body>Mini-tutorial
We have a user model that looks like this:
# app/models/user.rb
class User < ActiveRecord::Base
def first_name
'John'
end
def last_name
'Smith'
end
def title
'Mr.'
end
def name_visible?
true
end
def display_name
if name_visible?
[title, first_name, last_name].join(' ')
else
'(Name hidden)'
end
end
endwhere first_name, last_name and title are user table cloumns and display_name is only used to show the name while displaying information about the user. display_name doesn't really belong to the model and we want to move it to a separate class - the presenter.
We create a new file in app/presenters and move the display_name there:
class UserPresenter < ActiveRecord::Base
def display_name
if name_visible?
[title, first_name, last_name].join(' ')
else
'(Name hidden)'
end
end
endNow in our controller we can use the present method:
# app/controllers/users_cotroller.rb
class UsersController < ApplicationController
def show
@user = User.find(params[:id])
@user = present(@user)
end
endThis will add the display_name method to our @user. We can now use it in the view:
# app/views/users/show.html.erb
<h1><%=@user.display_name %> - User profile</h1>Contributing
- Fork it ( https://github.com/[my-github-username]/arch_presenter/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