Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/greena13/tint
Declarative object decorators for JSON APIs
https://github.com/greena13/tint
decorators draper json-api rails
Last synced: 4 days ago
JSON representation
Declarative object decorators for JSON APIs
- Host: GitHub
- URL: https://github.com/greena13/tint
- Owner: greena13
- License: mit
- Created: 2016-01-03T15:09:53.000Z (almost 9 years ago)
- Default Branch: master
- Last Pushed: 2019-04-14T15:09:50.000Z (over 5 years ago)
- Last Synced: 2024-12-06T00:10:04.054Z (22 days ago)
- Topics: decorators, draper, json-api, rails
- Language: Ruby
- Size: 21.5 KB
- Stars: 1
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE.txt
Awesome Lists containing this project
README
Tint
Easily define object decorators for JSON APIs using simple declarative syntax
## Installation
Add this line to your application's Gemfile:
gem 'tint'
And then execute:
$ bundle
Or install it yourself as:
$ gem install tint
## Usage
You can use Tint by creating a decorator class that inherits from `Tint::Decorator`
## Defining attributes
To include methods and attributes available on the decorated object, simply list them using `attributes`.
```ruby
# decorators/user_decorator.rb
class UserDecorator < Tint::Decorator
attributes :username, :first_name, :last_name
end
```You can map attributes to different names on the decorator by providing a hash as the final argument
```ruby
# decorators/user_decorator.rb
class UserDecorator < Tint::Decorator
attributes :username, :first_name, last_name: :surname # object.surname will be available as ['last_name']
end
```## Defining attributes for *_ids
The `ids_for` method adds `*Ids` values to a JSON object and ensures the corresponding association is automatically eager loaded:
```ruby
class ProductDecorator < Tint::Decorator
attributes :id, :description, :priceids_for :sales # will add a saleIds attribute to the JSON object
end
```It's possible to give the `*Ids` attribute a different name by providing the name of the association as a key-value pair:
```ruby
class ProductDecorator < Tint::Decorator
attributes :id, :description, :priceids_for sales: :purchase_identifiers # will add a purchaseIdentifiers attribute to the JSON object
end
```## Defining custom methods
Tint will use a decorator instance method in preference to one defined on the decorated object, so it is possible to customise how a particular attribute appears. The original definition of the attribute is available via the `object` instance variable.
```ruby
class ProductDecorator < Tint::Decorator
attributes :id, :description, :pricedef price
"$" + object.price
end
end
```It's also possible to define methods that are not available on the decorated object at all.
```ruby
class ProductDecorator < Tint::Decorator
attributes :id, :description, :on_saledef on_sale
SaleItems.include?(object)
end
end
```## Defining associations
The `decorates_association` method is used for declaring associations and delegating them to other decorators.
```ruby
# decorators/product_decorator.rb
class ProductDecorator < Tint::Decorator
attributes :id, :description
end# decorators/user_decorator.rb
class UserDecorator < Tint::Decorator
attributes :usernamedecorates_association :products
end
```By default, `decorates_association` uses the name of the association to guess the decorator it should use. In this case it will use `ProductDecorator`, but if you wished to render with `SpecialProductDecorator`, the `with` option may be used:
```ruby
decorates_association :product, with: SpecialProductDecorator
```You can decorate an association and make it available under a different name using the `as` option:
```ruby
decorates_association :product, as: :sale_item
```Multiple associations can be defined in the same statement using `decorates_associations`. Either, using interpolation to locate the correct decorator for each:
```ruby
decorates_associations :product, :address
```Or using the same decorator (in this case, `AddressDecorator`):
```ruby
decorates_associations :previous_address, :current_address, with: AddressDecorator
```## Eager loading associations
When you declare a new association using `decorates_association` or `decorates_associations`, Tint automatically eager loads the associations when the decorator is rendered as JSON and automatically prevents many N+1 queries. It does this by maintaining a list `eager_loads` which is available on all decorators.
```ruby
class UserDecorator < Tint::Decorator
attributes :usernamedecorates_association :products
endUserDecorator.eager_loads # [:products]
```If you need to manually add to the list of associations which are eager loaded for any reason, you can do so using the `eager_load` method
```ruby
class UserDecorator < Tint::Decorator
attributes :usernamedecorates_association :products
eager_load :addresses
endUserDecorator.eager_loads # [:products, :addresses]
```## Decorating a single instance
Tint maintains the interface defined by Draper for decorating objects. To decorate a single object, use the `decorate` method.
Using the `UserDecorator` defined above:
```ruby
# controllers/users_controller.rbclass UsersController < ApplicationController
def show
@user = User.find(params[:id]) #render json: UserDecorator.decorate(@user) # { username: "john_doe", firstName: "John", lastName: "Doe" }
endend
````decorate` also accepts an optional has of options. For more information about the supported options, see the [Draper documentation](https://github.com/drapergem/draper#adding-context).
## Decorating a collection
The `decorate_collection` method is used for decorating an instance of ActiveRecord::Relation (or any class that implements the same interface). It accepts all of the same options as the `decorate` method.
```ruby
# controllers/users_controller.rbclass UsersController < ApplicationController
def index
@users = User.allrender json: UserDecorator.decorate_collection(@users) # [ { username: "john_doe", firstName: "John", lastName: "Doe" }, ... ]
endend
```## Configuration
By default, Tint camelizes attribute names, however it's possible to configure Tint to use any of the following capitalization conventions:
```ruby
Tint.configuration do |config|
# attribute_naMe123 ==> attributeNaMe123 (Default)
# config.attribute_capitalization = :camel_case# attribute_naMe123 ==> attribute_na_me123
# config.attribute_capitalization = :snake_case# attribute_naMe123 ==> attribute-naMe123
# config.attribute_capitalization = :kebab_case# Converts symbols to strings
# config.attribute_capitalization = :none
end
```## Running the test suite
The test suite may be run simply using
rspec
## Contributions
Tint remains in its infancy and all pull requests, issues and feedback are welcome and appreciated.