Encore is a Ruby framework to help dealing with entities.
Installation
Add this line to your application's Gemfile:
gem 'encore'
And then execute:
$ bundle
Or install it yourself as:
$ gem install encore
Usage
Let’s say we have the UserEntity entity class bound to the User model:
class User < ActiveRecord::Base
end
class UserEntity
include Encore::Entity
expose :name
expose :email
expose :created_at, readonly: true
expose :updated_at, readonly: true
end
We can create a new User resource with attributes:
@entity = UserEntity.new
@entity.assign_attributes email: '[email protected]', name: 'Rémi Prévost'
@entity.save
When assigning attributes to an entity, we can pass either an :update or a :partial_update context.
With the (default) :partial_update context, Encore will assign new attributes and ignore the other exposed attributes. This makes sense in a PATCH HTTP request context.
new_attributes = { email: '[email protected]' }
@entity.assign_attributes new_attributes
@entity.object.email # => "[email protected]"
@entity.object.name # => "Rémi Prévost"
However, with the :update context, Encore will assign new attributes and set all non-provided exposed attributes to nil. This
makes sense in a PUT HTTP request context.
new_attributes = { email: '[email protected]' }
@entity.assign_attributes new_attributes, context: :update
@entity.object.email # => "[email protected]"
@entity.object.name # => nil
If we try to assign a value to a non-exposed or readonly attribute, Encore will raise an error.
@entity.assign_attributes email: '[email protected]', created_at: Time.now
# => raises #<Encore::Entity::Input::InvalidAttributeError: The #<Encore::Attribute UserEntity@created_at> attribute is not exposed.>
Associations
You can also expose associations.
class User < ActiveRecord::Base
belongs_to :organization
end
class Organization < ActiveRecord::Base
has_many :users
end
class UserEntity
include Encore::Entity
expose :name
expose_one :organization
end
Assigning new value for associations doesn’t save them right away.
@user = User.first # => #<User id=1 organization_id=1>
@entity = UserEntity.new(@user)
@entity.assign_attributes organization: 2
@entity.object.organization_id # => 1
Calling save on the entity saves them.
@entity.save
@entity.object.organization_id # => 2
Typical setup with Ruby on Rails
This is work-in-progress. There’s still missing stuff.
Model
# app/models/user.rb
class User < ActiveRecord::Base
end
Entity
# app/entities/user_entity.rb
class UserEntity
include Encore::Entity
expose :name
expose :email
expose :created_at, readonly: true
expose :updated_at, readonly: true
end
Routes
# config/routes.rb
Rails::Application.routes.draw do
resources :users do
# This makes Rails route PUT and PATCH requests to two separate actions
patch on: :member, action: :partial_update
end
end
Controller
# app/controllers/users_controller.rb
class UsersController < ApplicationController
before_action :fetch_user, only: [:update, :partial_update]
# POST /users
def create
@entity = UserEntity.new
@entity.assign_attributes(params[:user], context: :create)
process! @entity
# Here, `process!` is a shortcut for:
#
# if @entity.save
# render json: @entity, status: 201
# else
# render json: { errors: @entity.errors }, status: 422
# end
end
# PUT /users/:id
def update
@entity = UserEntity.new(@user)
@entity.assign_attributes(params[:user], context: :update)
process! @entity
end
# PATCH /users/:id
def partial_update
@entity = UserEntity.new(@user)
@entity.assign_attributes(params[:user], context: :partial_update)
process! @entity
end
protected
def fetch_user
@user = User.find(params[:id])
end
end
Todo
Please keep in mind that this gem is far from finished and totally not ready to use in production. This is something we’ve been wanting to build for a long time and now we’re finally taking the time do it right.
License
Encore is © 2013 Mirego and may be freely distributed under the New BSD license. See the LICENSE.md file.
The nut logo is based on this lovely icon by Alessandro Suraci, from The Noun Project. Used under a Creative Commons BY 3.0 license.
About Mirego
Mirego is a team of passionate people who believe that work is a place where you can innovate and have fun. We proudly build mobile applications for iPhone, iPad, Android, Blackberry, Windows Phone and Windows 8 in beautiful Quebec City.
We also love open-source software and we try to extract as much code as possible from our projects to give back to the community.