Presenter is an easy way of implementing the presenter design pattern in Rails.
With a naming convention based approach, easily define presenter classes to clean up your models and views, handling method delegation based on instance variable & file naming.
This should hopefully mean you can just use presenter objects in place of model objects throughout your app without effecting any behaviour - as you can still call your custom model methods and active record methods on the presenter objects.
This ultimately means all methods that belong to the model stay on the model itself and seperated from any methods which don't handle data.
All presenter classes inherit from ApplicationPresenter generated from the install to keep the same convention you see throughout the rest of your Rails app.
Add this line to your application's Gemfile and bundle:
gem 'presenter-rails'
$ bundle
Run the install generator
$ rails g presenter:install
Add this line to the top of your application.rb
# config/application.rb
require 'presenter'
Followed by this line inside the Application class
# config/application.rb
module YourAppName
class Application < Rails::Application
config.autoload_paths << Rails.root.join('app/presenters')
end
end
These instructions will use a 'User' model for example purposes. Just switch out User for your own model names
After you run the install generator, run
$ rails g presenter User
this will create a presenter file for one of your models and will inherit from ApplicationPresenter, example shown below:
# app/presenters/user_presenter.rb
class UserPresenter < ApplicationPresenter
end
Note: This provides you with a getter method: #subject. You can use #subject to acces the object you passed in when initializing the presenter. See below on how to do this.
# app/presenters/user_presenter.rb
def full_name
subject.first_name + ' ' + subject.last_name
end
If you do wish to override the initialize method, call super as demonstrated below:
def initialize(user, middle_name)
@user = user
@user.update middle_name: middle_name
# Make sure to pass your object to super.
super user
end
Now you can initialize a presenter. There are 2 methods for this, either directly initialize the object as usual with:
@user = UserPresenter.new(user)
or use our built in helper to accomplish the same thing:
# The present helper will work with a single model or a collection
@user = present(user)
@users = present(User.all)
Example provided shows how it would be used in a controller:
class UsersController < ApplicationController
def show
user = User.find(params[:id]) # get an instance of user
@user = present(user)
end
end
Now the user instance variable has access to all methods belonging to it's presenter and the model being passed in. This allows access to:
@user.name
# which returns first name and last name like 'Sam Sargent'
# or even call the normal model methods
@user.first_name
# which would delegate the method back to the user model being passed into the present helper
# returning something like 'Sam'
# Note: This works with all ActiveRecord methods too, just as if it's an object of the ActiveRecord class User
# allowing access to even @user.update(first_name: 'Finn') on the presenter object
#present is a method accessible in controllers and views for initializing new presenter objects
user = User.first
@user = present(user) # returns a presenter object for that model, replacing need to initialize with #new
# instead of
user = User.first
@user = UserPresenter.new(user)
# alternatively, pass in a collection to return an array of presenter objects
users = User.all # an active record relation
@users = present(users)
users = User.all.to_a # an array
@users = present(users)
For more detailed examples visit here
The gem is available as open source under the terms of the MIT License.