README.md in transmutation-0.2.2 vs README.md in transmutation-0.2.3
- old
+ new
@@ -1,22 +1,32 @@
# Transmutation
Transmutation is a Ruby gem that provides a simple way to serialize Ruby objects into JSON.
-It takes inspiration from the [Active Model Serializers](https://github.com/rails-api/active_model_serializers) gem, but strips away adapters.
+It also adds an opinionated way to automatically find and use serializer classes based on the object's class name and the caller's namespace - it takes inspiration from the [Active Model Serializers](https://github.com/rails-api/active_model_serializers) gem, but strips away adapters.
It aims to be a performant and elegant solution for serializing Ruby objects into JSON, with a touch of opinionated "magic" :sparkles:.
## Installation
-Install the gem and add to the application's Gemfile by executing:
+Install the gem and add to your application's Gemfile by executing:
- $ bundle add transmutation
+```bash
+bundle add transmutation
+```
+or manually add the following to your Gemfile:
+
+```ruby
+gem "transmutation"
+```
+
If bundler is not being used to manage dependencies, install the gem by executing:
- $ gem install transmutation
+```bash
+gem install transmutation
+```
## Usage
### Basic Usage
@@ -46,17 +56,20 @@
UserSerializer.new(user).to_json # => "{\"id\":1,\"name\":\"John Doe\",\"email\":\"john@example.com\"}"
```
As long as your object responds to the attributes defined in the serializer, it can be serialized.
- - Struct
+ <details>
+ <summary>Struct</summary>
```ruby
User = Struct.new(:id, :name, :email)
```
+ </details>
- - Class
+ <details>
+ <summary>Class</summary>
```ruby
class User
attr_reader :id, :name, :email
@@ -65,12 +78,14 @@
@name = name
@email = email
end
end
```
+ </details>
- - ActiveRecord
+ <details>
+ <summary>ActiveRecord</summary>
```ruby
# == Schema Information
#
# Table name: users
@@ -79,17 +94,144 @@
# name :string
# email :string
class User < ApplicationRecord
end
```
+ </details>
-### Using the `Transmutation::Serialization` module
+### The `#serialize` method
+When you include the `Transmutation::Serialization` module in your class, you can use the `#serialize` method to serialize an object.
+
+It will attempt to find a serializer class based on the object's class name along with the caller's namespace.
+
+```ruby
+include Transmutation::Serialization
+
+serialize(User.new) # => UserSerializer.new(User.new)
+```
+
+If no serializer class is found, it will return the object as is.
+
+### With Ruby on Rails
+
+When then `Transmutation::Serialization` module is included in a Rails controller, it also extends your `render` calls.
+
+```ruby
+class Api::V1::UsersController < ApplicationController
+ include Transmutation::Serialization
+
+ def show
+ user = User.find(params[:id])
+
+ render json: user
+ end
+end
+```
+
+This will attempt to bubble up the controller namespaces to find a defined serializer class:
+
+- `Api::V1::UserSerializer`
+- `Api::UserSerializer`
+- `UserSerializer`
+
+This calls the `#serialize` method under the hood.
+
+If no serializer class is found, it will fall back to the default behavior of rendering the object as JSON.
+
+You can disable this behaviour by passing `serialize: false` to the `render` method.
+
+```ruby
+render json: user, serialize: false # => user.to_json
+```
+
+## Configuration
+
+You can override the serialization lookup by passing the following options:
+
+- `namespace`: The namespace to use when looking up the serializer class.
+
+ ```ruby
+ render json: user, namespace: "V1" # => Api::V1::V1::UserSerializer
+ ```
+
+ To prevent caller namespaces from being appended to the provided namespace, prefix the namespace with `::`.
+
+ ```ruby
+ render json: user, namespace: "::V1" # => V1::UserSerializer
+ ```
+
+ The `namespace` key is forwarded to the `#serialize` method.
+
+ ```ruby
+ render json: user, namespace: "V1" # => serialize(user, namespace: "V1")
+ ```
+
+- `serializer`: The serializer class to use.
+
+ ```ruby
+ render json: user, serializer: "SuperUserSerializer" # => Api::V1::SuperUserSerializer
+ ```
+
+ To prevent all namespaces from being appended to the serializer class, prefix the serializer class with `::`.
+
+ ```ruby
+ render json: user, serializer: "::SuperUserSerializer" # => SuperUserSerializer
+ ```
+
+ The `serializer` key is forwarded to the `#serialize` method.
+
+ ```ruby
+ render json: user, serializer: "SuperUserSerializer" # => serialize(user, serializer: "SuperUserSerializer")
+ ```
+
+## Opinionated Architecture
+
+If you follow the pattern outlined below, you can take full advantage of the automatic serializer lookup.
+
+### File Structure
+
+```
+.
+└── app/
+ ├── controllers/
+ │ └── api/
+ │ ├── v1/
+ │ │ └── users_controller.rb
+ │ └── v2
+ │ └── users_controller.rb
+ ├── models/
+ │ └── user.rb
+ └── serializers/
+ └── api/
+ ├── v1/
+ │ └── user_serializer.rb
+ ├── v2/
+ │ └── user_serializer.rb
+ └── user_serializer.rb
+```
+
+### Serializers
+
+```ruby
+class Api::UserSerializer < Transmutation::Serializer
+ attributes :id, :name, :email
+end
+
+class Api::V1::UserSerializer < Api::UserSerializer
+ attributes :phone # Added in V1
+end
+
+class Api::V2::UserSerializer < Api::UserSerializer
+ attributes :avatar # Added in V2
+end
+```
+
+To remove attributes, it is recommended to redefine all attributes and start anew. This acts as a reset and makes serializer inheritance much easier to follow.
+
## 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`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
## Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/spellbook-technology/transmutation. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/spellbook-technology/transmutation/blob/main/CODE_OF_CONDUCT.md).