A simple and Rubyish view helper for Rails 4, Rails 5, Rails 6, Rails 7, and Rails 8. Keep your helpers and views Object-Oriented!
- automatically mixes decorator module into corresponding model only when:
- passing a model or collection of models or an instance of ActiveRecord::Relation from controllers to views
 - rendering partials with models (using 
:collectionor:objector:localsexplicitly or implicitly) - fetching already decorated Active Record model object's association
 
 - the decorator module runs in the model's context. So, you can directly call any attributes or methods in the decorator module
 - since decorators are considered as sort of helpers, you can also call any ActionView's helper methods such as 
content_tagorlink_to 
- 
Ruby 2.1.x, 2.2.x, 2.3.x, 2.4.x, 2.5.x, 2.6.x, 2.7.x, 3.0.x, 3.1.x, 3.2.x, 3.3.x, 3.4.x, and 3.5 (trunk)
 - 
Rails 4.2.x, 5.0, 5.1, 5.2, 6.0, 6.1, 7.0, 7.1, 7.2, 8.0, and 8.1 (edge)
 
ActiveRecord, ActiveResource, and any kind of ORMs that uses Ruby Objects as model objects
- bundle 'active_decorator' gem
 - create a decorator module for each AR model. For example, a decorator for a model 
Usershould be namedUserDecorator. You can use the generator for doing this (% rails g decorator user) - Then it's all done. Without altering any single line of the existing code, the decorator modules will be automatically mixed into your models only in the view context.
 
- Model
 
class Author < ActiveRecord::Base
  # first_name:string last_name:string
end- Controller
 
class AuthorsController < ApplicationController
  def show(id)  # powered by action_args
    @author = Author.find id
  end
end- Decorator
 
module AuthorDecorator
  def full_name
    "#{first_name} #{last_name}"
  end
end- View
 
<%# @author here is auto-decorated in between the controller and the view %>
<p><%= @author.full_name %></p>- Models
 
class Author < ActiveRecord::Base
  # name:string
  has_many :books
end
class Book < ActiveRecord::Base
  # title:string url:string
  belongs_to :author
end- Controller
 
class AuthorsController < ApplicationController
  def show(id)
    @author = Author.find id
  end
end- Decorator
 
module BookDecorator
  def link
    link_to title, url
  end
end- View
 
<p><%= @author.name %></p>
<ul>
<% @author.books.order(:id).each do |book| %>
  <%# `book` here is auto-decorated because @author is a decorated instance %>
  <li><%= book.link %></li>
<% end %>
</ul>Sometimes you may want to use decorators outside of Action View, for example,
for background tasks for ActiveJob.
For such use case, ActiveDecorator module provides run_with method
that takes some kind of Action View and a block.
ActiveDecorator::ViewContext.run_with ApplicationController.new.view_context do
  ## perform some heavy jobs here
endYou can test a decorator using your favorite test framework by decorating the model instance with
ActiveDecorator::Decorator.instance.decorate(model_instance)Considering an Organization model and its simple decorator:
module OrganizationDecorator
  def full_name
    "#{first_name} #{last_name}"
  end
endAn RSpec test would look like:
describe '#full_name' do
  it 'returns the full organization name' do
    organization = Organization.new(first_name: 'John', last_name: 'Doe')
    decorated_organization = ActiveDecorator::Decorator.instance.decorate(organization)
    expect(decorated_organization.full_name).to eq('John Doe')
  end
endBy default, ActiveDecorator searches a decorator module named target_class.name + "Decorator"
If you would like a different rule, you can configure in your initializer.
ActiveDecorator.configure do |config|
  config.decorator_suffix = 'Presenter'
end- Fork, fix, then send me a pull request.
 
Copyright (c) 2011 Akira Matsuda. See MIT-LICENSE for further details.