Dynamically extended helper module in presenter class

# models/movie.rb
class Movie
  include ActiveModel::Model

  attr_accessor :id, :title, :genres, :date, :rating
end
# presenters/movies_presenter.rb
require 'erb'

class MoviesPresenter
  def initialize(movies, display_formatter: nil)
    @movies            = movies
    @display_formatter = display_formatter || Object.new.extend(MoviesHelper)
  end

  def render
    ERB.new(<<~'HTML').result(binding).html_safe
      <ul>
        <% @movies.each do |m| %>
        <li><%= @display_formatter.short_display_name(m) %></li>
        <% end %>
      </ul>
    HTML
  end
end
# routes.rb
resources :movies, only: :index

# controller/movies_controller.rb
class MoviesController < ApplicationController
  def index
    @movies = MoviesPresenter.new(
      [
        Movie.new(id: 1, title: 'Fist Fight', genres: ['comedy'], date: '16-02-2017'.to_date, rating: 6.0),
        Movie.new(id:     2,
                  title:  'Power Ranges',
                  genres: %w[action sci-fi adventures],
                  date:   '23-03-2017'.to_date,
                  rating: 6.6),
        Movie.new(id:     3,
                  title:  'King Arthur',
                  genres: %w[action drama fantasy],
                  date:   '27-04-2017'.to_date,
                  rating: 6.4),
        Movie.new(id:     4,
                  title:  'Alien: Covenant',
                  genres: %w[horror sci-fi suspense],
                  date:   '09-05-2017'.to_date,
                  rating: 6.0)
      ]
    )
  end
end
# helpers/movies_helper.rb
module MoviesHelper
  def short_display_name(movie)
    <<~HTML.html_safe
      <b>#{movie.title}</b>, #{movie.date.strftime('%v')}. <u>Rating: <i>#{movie.rating}</i></u>
    HTML
  end
end
# views/movies/index.html.erb
<h1>Movies List</h1>

<%= @movies.render %>
Alexander M about 5 years ago
This website uses short-lived cookies to improve usability.
Accept or learn more