Dekorator
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.
Compatibility
- Ruby 3.1+
- Rails 7.0+
Installation
Add this line to your application Gemfile
:
gem "dekorator"
And then execute:
$ bundle
Getting started
Run the following command to set up your project:
$ rails generate dekorator:install
This command will create an ApplicationDecorator
file.
Usage
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
end
Decorate from a controller
class UsersController < ApplicationController
def index
@users = decorate User.all
end
def show
@user = decorate User.find(params[:id])
end
end
Decorate from a view
# app/views/users/index.html.erb
<ul>
<% decorate(@users).each do |user| %>
<li><%= user.full_name %></li>
<% end %>
</ul>
Decorate outside a controller/view
UserDecorate.decorate(User.first) # => UserDecorator
Associations
If 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
...
end
In this example, UserDecorator#posts
will be decorated as #decorated_posts
.
decorated_user = decorate(User.first)
decorated_user # => UserDecorator
decorated_user.decorated_posts.first # => PostDecorator
Custom decorator
By 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 # => AdminDecorator
You 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 # => ArticleDecorator
Compatibility
Devise
If 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
end
Testing
rails generate decorator user
also generates a testing file based on your
configuration.
You can test a decorator the same way you do for helpers.
RSpec
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
end
Development
After 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.
Contributing
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.
License
The gem is available as open source under the terms of the MIT License.
Code of Conduct
Everyone interacting in the Dekorator project codebases, issue trackers, chat rooms and mailing lists is expected to follow the code of conduct.