0.0
No release in over 3 years
Low commit activity in last 3 years
Presenter design pattern for Rails.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies

Development

>= 0
~> 5.0.2
 Project Readme

presenter-rails

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.

Installation

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

Usage

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

Initializing the presenter

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)

(More on this below)

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

Helper methods

#present

#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

License

The gem is available as open source under the terms of the MIT License.