Encore
Encore is a Ruby framework to help dealing with entities.

--- ## Installation Add this line to your application's Gemfile: ```ruby gem 'encore' ``` And then execute: ```bash $ bundle ``` Or install it yourself as: ```bash $ gem install encore ``` ## Usage Let’s say we have the `UserEntity` entity class bound to the `User` model: ```ruby 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: ```ruby @entity = UserEntity.new @entity.assign_attributes email: 'remi@example.com', 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. ```ruby new_attributes = { email: 'remi+new@example.com' } @entity.assign_attributes new_attributes @entity.object.email # => "remi+new@example.com" @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. ```ruby new_attributes = { email: 'remi+new-again@example.com' } @entity.assign_attributes new_attributes, context: :update @entity.object.email # => "remi+new-again@example.com" @entity.object.name # => nil ``` If we try to assign a value to a non-exposed or readonly attribute, Encore will raise an error. ```ruby @entity.assign_attributes email: 'remi+new@example.com', created_at: Time.now # => raises # attribute is not exposed.> ``` ### Associations You can also expose associations. ```ruby 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. ```ruby @user = User.first # => # @entity = UserEntity.new(@user) @entity.assign_attributes organization: 2 @entity.object.organization_id # => 1 ``` Calling `save` on the entity saves them. ```ruby @entity.save @entity.object.organization_id # => 2 ``` ## Typical setup with Ruby on Rails _This is work-in-progress. There’s still missing stuff._ ### Model ```ruby # app/models/user.rb class User < ActiveRecord::Base end ``` ### Entity ```ruby # 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 ```ruby # 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 ```ruby # 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](http://www.mirego.com) and may be freely distributed under the [New BSD license](http://opensource.org/licenses/BSD-3-Clause). See the [`LICENSE.md`](https://github.com/mirego/encore/blob/master/LICENSE.md) file. The nut logo is based on [this lovely icon](http://thenounproject.com/noun/hazelnuts/#icon-No3618) by [Alessandro Suraci](http://thenounproject.com/alessandro.suraci/), from The Noun Project. Used under a [Creative Commons BY 3.0](http://creativecommons.org/licenses/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](http://mirego.com/en/iphone-app-development/ "iPhone application development"), [iPad](http://mirego.com/en/ipad-app-development/ "iPad application development"), [Android](http://mirego.com/en/android-app-development/ "Android application development"), [Blackberry](http://mirego.com/en/blackberry-app-development/ "Blackberry application development"), [Windows Phone](http://mirego.com/en/windows-phone-app-development/ "Windows Phone application development") and [Windows 8](http://mirego.com/en/windows-8-app-development/ "Windows 8 application development") in beautiful Quebec City. We also love [open-source software](http://open.mirego.com/) and we try to extract as much code as possible from our projects to give back to the community.