/object_json_mapper

Add the power of ActiveRecord to your API client.

Primary LanguageRubyMIT LicenseMIT

ObjectJSONMapper

Gem Version CircleCI

Installation

Add this line to your application's Gemfile:

gem 'object_json_mapper'

And then execute:

$ bundle

Or install it yourself as:

$ gem install object_json_mapper

Usage

Set default url for your API in config/initializers/object_json_mapper.rb:

require 'object_json_mapper'

ObjectJSONMapper.configure do |config|
  # Required
  config.base_url = 'http://localhost:3000'

  # Optional
  config.headers  = {
    'Authorization' => 'secret-token'
  }
end

Define class, e.g. User:

class User < ObjectJSONMapper::Base
end

Find

User.find(1)
# => GET http://localhost:3000/users/1

Where

User.where(id: 1)
# => GET http://localhost:3000/users?id=1

User.where(id: 1).where(name: 'Name')
# => GET http://localhost:3000/users?id=1&name=Name

Create

User.create(name: 'Name')
# => POST http://localhost:3000/users
# =>   {
# =>     name: 'Name'
# =>   }

Update

u = User.find(1)
u.update(name: 'Name')
# => PATCH http://localhost:3000/users/1
# =>   {
# =>     name: 'Name'
# =>   }

Delete

u = User.find(1)
u.delete
# => DELETE http://localhost:3000/users/1

Attributes

Defaults

Executes given Proc if value is nil.

class User < ObjectJSONMapper::Base
  attribute :created_at, default: -> { DateTime.now }
end

Coercion

Expects a object with #call interface to return modified value.

class User < ObjectJSONMapper::Base
  attribute :created_at, type: Dry::Types['form.date_time']
end

Associations

HasMany

Returns a Relation with model objects.

class User < ObjectJSONMapper::Base
  has_many :posts
end

User.find(1).posts
# => GET http://localhost:3000/users/1/posts

BelongsTo / HasOne

Returns a single model object.

class Post < ObjectJSONMapper::Base
  belongs_to :user
  has_one :image
end

Post.find(1).user
# => GET http://localhost:3000/posts/1/user

Post.find(1).image
# => GET http://localhost:3000/posts/1/image

Scope

Defines a scope for current model and all it relations. It's possible to chain #where methods and defined scopes in any order.

class User < ObjectJSONMapper::Base
  scope :published, -> { where(published: true) }
  scope :active, -> { where(active: true) }
end

User.published
# => GET http://localhost:3000/users?published=true

User.published.active
# => GET http://localhost:3000/users?published=true&active=true

User.published.where(active: true)
# => GET http://localhost:3000/users?published=true&active=true

User.where(active: true).published
# => GET http://localhost:3000/users?active=true&published=true

Pluck

User.where(published: true).pluck(:id, :email)
# => GET http://localhost:3000/users?published=true
# => [[1, 'first@example.com', [2, 'second@example.com']]

None

Returns a chainable relation without records, wouldn't make any queries.

User.none
# => []

User.where(id: 1).none
# => []

User.none.where(id: 1)
# => []

Root

Allows to change resource path for model client.

User.root('people').where(name: 'Name')
# => GET http://localhost:3000/people?name=Name

Paginate

Kaminari required.

Yields all pages.

User.where(name: 'Name').paginate { |user| hello(user) }
# => GET http://localhost:3000/people?name=Name?page=1
# => GET http://localhost:3000/people?name=Name?page=2
# => GET http://localhost:3000/people?name=Name?page=3

Configure

Available options:

  • root_url - resource path for current model.
class User < ObjectJSONMapper::Base
  configure do |c|
    c.root_url = 'people'
  end
end

User.all
# => GET http://localhost:3000/people

User.find(1)
# => GET http://localhost:3000/people/1

User.find(1).posts
# => GET http://localhost:3000/people/1
# => GET http://localhost:3000/people/1/posts

License

ObjectJSONMapper is released under the MIT License.

About

ObjectJSONMapper is maintained by Inspire.