MetaPresenter is a Ruby gem for writing highly focused and testable Rails view presenter classes. For each controller/action pair you get a presenter class in app/presenters that you can use in your views with presenter.method_name. This helps you decompose your helper logic into tight, easily testable classes.
gem 'meta_presenter'bundle installclass ApplicationController < ActionController::Base
include MetaPresenter::Helpers
end# mailers are supported too
class ApplicationMailer < ActionMailer::Base
include MetaPresenter::Helpers
endApplicationPresenter methods can be used anywhere in the app. This example makes presenter.page_title and presenter.last_login accessible from all views.
# app/presenters/application_presenter.rb
class ApplicationPresenter < MetaPresenter::BasePresenter
def page_title
"My App"
end
def last_login
# controller methods are available to
# presenters in the same namespace
time = current_user.last_login_at
distance_of_time_in_words_to_now(time)
end
endThis example makes presenter.tooltip(text) available for all actions on PagesController:
# app/presenters/pages_presenter.rb
class PagesPresenter < ApplicationPresenter
def tooltip(text)
content_tag(:p, text, class: "font-body1")
end
end<!-- app/views/pages/about.html.erb -->
<h1>About</h1>
<p data-tipsy-content="<%= presenter.tooltip("Don't Be Evil") %>">Gloogle</p>This example makes presenter.greeting accessible from views. It also delegates undefined methods to current_user, so presenter.email would call current_user.email:
# app/presenters/pages/home_presenter.rb
class Pages::HomePresenter < PagesPresenter
# can also delegate specific methods. ex:
# delegate :email, :last, to: :current_user
delegate_all_to = :current_user
def greeting
"Hello, #{name}"
end
end<!-- app/views/pages/home.html.erb -->
<h1>Home</h1>
<p><%= presenter.greeting %></p>
<p>Last login <%= presenter.last_login %></p>Note that presenters mirror the namespace of controllers.
app/
controllers/
application_controller.rb
pages_controller.rb
presenters/
application_presenter.rb
pages_presenter.rb
pages/
home_presenter.rb
logs_presenter.rb
views
pages
home.html.erb
logs.html.erb
spec/ (or test/)
presenters/
application_presenter_spec.rb
pages_presenter_spec.rb
pages/
home_presenter_spec.rb
logs_presenter_spec.rb
If you want to customize the presenter method you can specify a shorthand by adding an alias_method to your controller or mailer:
class ApplicationController < ActionController::Base
including MetaPresenter
# So convenient!
alias_method :presenter, :pr
endMetaPresenter supports Ruby >= 3.0.0 and ActionPack/ActionMailer >= 6, or >= 7.0.1 for Rails 7 (7.0.0 has a bug)
To run the specs for the currently running Ruby version, run bundle install and then bundle exec rspec. To run specs for every supported version of ActionPack, run bundle exec appraisal install and then bundle exec appraisal rspec.
Make sure the specs pass, bump the version number in meta_presenter.gemspec, build the gem with gem build meta_presenter.gemspec. Commit your changes and push to Github, then tag the commit with the current release number using Github's Releases interface (use the format vx.x.x, where x is the semantic version number). You can pull the latest tags to your local repo with git pull --tags. Finally, push the gem with gem push meta_presenter-version-number-here.gem.
- Add a
rake meta_presenter:installthat generates the scaffolding for you - Make sure directions are clear for manually creating presenters
- create an example app and link to the repo for it in this README
- add support for layout-level presenters
- Fork it
- Create your feature branch (
git checkout -b feature/my-new-feature) or bugfix branch (git checkout -b bugfix/my-helpful-bugfix) - Commit your changes (
git commit -am 'Add some feature') - Push to the branch (
git push origin feature/my-new-feature) - Make sure specs are passing (
bundle exec rspec) - Create new Pull Request
To run specs against different versions of Rails:
bundle exec appraisal install #install dependencies for each ruby version
bundle exec appraisal rails6 rspec #run rails 6 specs on current Ruby
bundle exec appraisal rails7 rspec #run rails 7 specs on current RubySee the LICENSE file.

