https://github.com/brianp/garnish
Provides an easy to use and transparent system for implementing the Decorator Pattern
https://github.com/brianp/garnish
Last synced: 8 months ago
JSON representation
Provides an easy to use and transparent system for implementing the Decorator Pattern
- Host: GitHub
- URL: https://github.com/brianp/garnish
- Owner: brianp
- License: mit
- Created: 2011-10-26T04:27:35.000Z (over 14 years ago)
- Default Branch: master
- Last Pushed: 2013-10-03T05:01:48.000Z (over 12 years ago)
- Last Synced: 2025-03-31T09:11:26.085Z (about 1 year ago)
- Language: Ruby
- Homepage:
- Size: 254 KB
- Stars: 14
- Watchers: 3
- Forks: 4
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README

[](https://travis-ci.org/brianp/garnish)
[](https://codeclimate.com/github/brianp/garnish)
[RDocs](http://rdoc.info/projects/brianp/garnish)
Garnish is a Presenter / Decorator pattern for models in Rails. It gives a home to presentation level view logic that normally litters helpers and view files. Using it can help you:
* Keep helper files and views clean of if/else statements and other logic
* Better define an interface for views to interact with models
* Maintain a very familiar OOP pattern within your project directory
* Keep you controller code clean by never having to instantiate the presenters
* Handle Decorating / Presenting standard Rails relationships
## Requirements
Garnish Has been tested with
* Rails 3.1+
* Ruby 1.9.3, 2.0.0, JRuby, Rubinius
* ActiveRecord, Mongoid
_Notes:_ `>1.9.3` requires you to lock `activesupport` and `actionpack` at
`>4.0.0`. For this reason we have officially dropped support for ruby
1.9.2 and earlier. Although it will most likely work without a problem.
## Installation
In **Rails 3**, add this to your Gemfile and run the `bundle` command.
`gem "garnish"`
## Getting Started
A lot of magic happens with Garnish in an attempt to make things incredibly simple for you.
### 1. Define You Presenters
Create a folder in `app/` called presenters. ex `app/presenters/`
Create a presenter matching the name of your model in your presenters folder. ex `app/presenters/user_presenter.rb`
Define the `user_presenter`
```ruby
module UserPresenter
include Garnish::Presenter
end
```
## 2. Add methods to your presenter
Define methods in your presenter as regular instance methods
```ruby
module UserPresenter
include Garnish::Presenter
def greeting
if last_login.nil?
"Welcome #{name}, can we offer you a tour?"
else
"Welcome back #{name}"
end
end
end
```
### 3. Add the `garnish` call
In `app/controllers/application_controller.rb` add the garnish call.
```ruby
class ApplicationController < ActionController::Base
protect_from_forgery
garnish
end
```
Or If you don't want to use Garnish application wide simply add the call into a specific controller.
### 4. Use respond_with
The only change you need to make to start using your presenters now is to use respond_with inside any controller that has been garnished
`app/controllers/user_controller.rb`
```ruby
def show
@user = User.find(params[:id])
respond_with @user do |format|
format.html # show.html.erb
end
end
```
Garnish will now find and load presenters for any instance variables you set inside your action. *NOT* just the ivar passed to the respond_with block.
### 5. Start using your presenter methods
`app/views/users/show.html.erb`
```erb
<%= @user.greeting %>
```
## View Helpers
Garnish plays very nicely when adding view helper methods into your presenter. Just treat them like a regular method.
```ruby
module UserPresenter
include Garnish::Presenter
def profile_pic
image_tag profile_pic unless profile_pic.nil?
end
end
```
## Relationships
The real reason I got down to business. If I'm using presenters in my views I probably have presenters for multiple objects.
```ruby
class User < ActiveRecord::Base
has_many :items
end
class Item < ActiveRecord::Base
belongs_to :user
end
```
Assuming I have presenters for both of these models
```ruby
module UserPresenter
include Garnish::Presenter
end
module ItemPresenter
include Garnish::Presenter
def picture
image_tag profile_pic unless profile_pic.nil?
end
end
```
In my view when I'm accessing a user's items via the association what I really want is an Item extended with presenter methods not just a regular item.
Garnish handles this for us. Anytime a relationship is accessed on a garnished resource the returned resources will also be extended with their presenter methods.
```erb
<%= @user.items.first.picture %>
```
Works with no effort what so ever.
## Questions or Problems?
If you have any issues with Garnish which you cannot find the solution to, please add an [issue on GitHub](https://github.com/brianp/garnish/issues) or fork the project and send a pull request.
To get the specs running you should call `bundle` and then `rake`. See the [spec/README](https://github.com/brianp/garnish/blob/master/spec/README.md) for more information.
## Special Thanks
[Fraser Valley Ruby Brigade](http://www.fvrb.org/)
The Ruby Moguls
Garnish was inspired by [draper](https://github.com/jcasimir/draper/) and the RailsCast Pro episode #287 Presenters from Scratch.
See the [CHANGELOG](https://github.com/brianp/garnish/blob/master/CHANGELOG.rdoc) for the full list.