samuel02/karta

View on GitHub
README.md

Summary

Maintainability
Test Coverage
# Karta
[![GitHub](http://img.shields.io/badge/github-samuel02/karta-blue.svg)](http://github.com/samuel02/karta)
[![Documentation](http://img.shields.io/badge/docs-rdoc.info-blue.svg)](http://rubydoc.org/gems/karta/frames)
[![Gem Version](https://badge.fury.io/rb/karta.svg)](https://badge.fury.io/rb/karta)
[![Build Status](https://travis-ci.org/samuel02/karta.svg?branch=master)](https://travis-ci.org/samuel02/karta)
[![Code Climate](https://codeclimate.com/github/samuel02/karta/badges/gpa.svg)](https://codeclimate.com/github/samuel02/karta)
[![Test Coverage](https://codeclimate.com/github/samuel02/karta/badges/coverage.svg)](https://codeclimate.com/github/samuel02/karta/coverage)
[![License](http://img.shields.io/badge/license-MIT-yellowgreen.svg)](#license)

Karta is a very light-weight Ruby library that makes it easy to create mapper objects in a Ruby application. The mapper object makes it easy to map or transform one object into an other. The main use case is to transform data objects from an domain to another domain, e.g. map a `Twitter::User` to `User`. Instead of having to, for example, define a method `#from_twitter_user` on the `User` class which sets all attributes correctly a mapper object is created which defines all mappings.

## Installation

Add this line to your application's Gemfile:

```ruby
gem 'karta'
```

And then execute:

    $ bundle

Or install it yourself as:

    $ gem install karta

## Usage

### Setting up a mapper
The main functionality of Karta is used by letting a class inherit from `Karta::Mapper`. By doing so the class gets a `#map` method which will run all methods starting with `map_` with the two objects as arguments.

##### Example
```ruby
class MyTwitterMapper < Karta::Mapper
  def map_email(twitter_user, user)
    user.email = twitter_user.twitter_email
  end

  def map_username(twitter_user, user)
    user.username = twitter_user.twitter_handle.gsub('@', '')
  end
end

# Mapping from one instance to another, overriding
# values if already set
twitter_user = ...
user = ...
mapped_user = MyTwitterMapper.new.map(from: twitter_user, to: user)

# Mapping from an instance to a class, will return
# a new instance of the class
twitter_user = ...
user = MyTwitterMapper.new.map(from: twitter_user, to: User)

# Using class method (which instantiates before running map on the instance)
twitter_user = ...
user = MyTwitterMapper.map(from: twitter_user, to: User)
```

### Using the mapper registry
To simplify cases when an application has several mappers it is possible to register mappers and then only use `Karta.map` to map between two objects.

##### Example

```ruby
class MyMapper < Karta::Mapper
  # map methods...
end

Karta.register_mapper MyMapper, from_klass: Twitter::User, to_klass: User

# There is an option to not have to specify from and to class
# when registering the mapper. This relies on reflection and
# requires the mapper to have a class name on the correct format
# (`[from class]To[to class]Mapper`) for example `FooToBarMapper`.
class FooToBarMapper < Karta::Mapper
  # map methods
end

# Register mapper with from_klass = Foo and to_klass = Bar
Karta.register_mapper FooToBarMapper

# Using Karta.map to map between two objects
twitter_user = ...
user = Karta.map(from: twitter_user, to: User)

foo = ...
bar = Karta.map(from: foo, to Bar)
```

### One to one mappings
Sometimes you have fields that could be mapped directly without performing any transformations instead of having to define mapping methods for each you can use `one_to_one_mapping :attr`.

##### Example

```ruby
class FooToBarMapper < Karta::Mapper
  one_to_one_mapping :email
end

foo = ...
bar = FooToBarMapper.map(from: foo, to Bar)
puts foo.email == bar.email # => true
```

## Contributing

1. Fork it ( https://github.com/samuel02/karta/fork )
2. Create your feature branch (`git checkout -b my-new-feature`)
3. Commit your changes (`git commit -am 'Add some feature'`)
4. Push to the branch (`git push origin my-new-feature`)
5. Create a new Pull Request