Dekorator is a lightweight library to implement presenters and/or decorators in your Rails app. It has less features than draper and aims at having a lower memory footprint.
This gem has been inspired by our Rails development practices at Pantographe, and the Ruby memory, ActiveRecord and Draper talk by Benoit Tigeot.
- Ruby 3.2+
- Rails 7.2+
Add this line to your application Gemfile:
gem "dekorator"And then execute:
$ bundle
Run the following command to set up your project:
$ rails generate dekorator:install
This command will create an ApplicationDecorator file.
Generate a new decorator with the decorator generator:
$ rails generate decorator user
This command will generate the following file:
class UserDecorator < ApplicationDecorator
include ActionView::Helpers::TextHelper
decorates_association :posts
def full_name
[first_name, last_name].join(" ")
end
def biography_summary
truncate(biography, length: 170)
end
endclass UsersController < ApplicationController
def index
@users = decorate User.all
end
def show
@user = decorate User.find(params[:id])
end
end# app/views/users/index.html.erb
<ul>
<% decorate(@users).each do |user| %>
<li><%= user.full_name %></li>
<% end %>
</ul>UserDecorate.decorate(User.first) # => UserDecoratorIf you want to automatically decorate an association for a decorated object,
you have to use #decorates_association as following:
class UserDecorator < ApplicationDecorator
decorates_association :posts
...
end
class PostDecorator < ApplicationDecorator
...
endIn this example, UserDecorator#posts will be decorated as #decorated_posts.
decorated_user = decorate(User.first)
decorated_user # => UserDecorator
decorated_user.decorated_posts.first # => PostDecoratorBy default, Dekorator searches for the decorator class by adding Decorator at the end.
For User, Dekorator looks for the UserDecorator class, and for User::Profile
it looks for User::ProfileDecorator.
If you want to create a specific decorator or sub-decorator, you can simply specify the decorator class that should be used.
class AdminDecorator < ApplicationDecorator
...
end
decorated_user = decorate(User.first, with: AdminDecorator)
decorated_user # => AdminDecoratorYou can also specify the decorator for associations:
class UserDecorator < ApplicationDecorator
decorates_association :posts, with: ArticleDecorator
...
end
class ArticleDecorator < ApplicationDecorator
end
decorated_user = decorate(User.first)
decorated_user # => UserDecorator
decorated_user.decorated_posts.first # => ArticleDecoratorIf you use the Devise gem you may have an issue if you decorate your
User model.
You must define #devise_scope as following. Devise needs to manage with the
User model (https://github.com/plataformatec/devise/blob/369ba267efaa10d01c8dba59b09c3b94dd9e5551/lib/devise/mapping.rb#L35).
class UserDecorator < ApplicationDecorator
...
def devise_scope
__getobj__
end
endrails generate decorator user also generates a testing file based on your
configuration.
You can test a decorator the same way you do for helpers.
describe UserDecorator, type: :decorator do
let(:object) { User.new(first_name: "John", last_name: "Doe") }
let(:decorated_user) { described_class.new(object) }
describe "#full_name" do
it { expect(decorated_user.full_name).to eq("John Doe") }
end
endAfter checking out the repo, run bin/setup to install dependencies. Then, run
rake spec to run the tests. You can also run bin/console for an interactive
prompt that will allow you to experiment.
To install this gem onto your local machine, run bundle exec rake install.
To release a new version, update the version number in version.rb, then
run bundle exec rake release, which will create a git tag for the version,
push git commits and tags, and push the .gem file to rubygems.org.
Bug reports and pull requests are welcome on GitHub at https://github.com/komposable/dekorator. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the Contributor Covenant code of conduct.
The gem is available as open source under the terms of the MIT License.
Everyone interacting in the Dekorator project codebases, issue trackers, chat rooms and mailing lists is expected to follow the code of conduct.