Code Monkey home page Code Monkey logo

laravel-model-transformer's Introduction

Laravel 5 Model Transformers

Latest Version on Packagist Software License Total Downloads

This package helps API developers to easily transform Eloquent models into arrays that are convertible to JSON.

Here's how you use it, let's say you have a model with the following data:

{
	"name": "iPhone",
	"type": 1
}

Here you use a numerical value to represent the different types, you also have a mutator in the model that maps the numerical value to a string.

Inside the controller we can transform the model to be represented into more API friendly structure.

<?php
class SomeController{
	function getIndex(){
		$product = Product::find(1);
		
		return response([
			"product" => ProductTransformer::transform($product)
		]);
	}
}

The above code will result a JSON string that may look like this:

{
	"product": {
		"name": "iPhone",
		"type": {
			"key": 1,
			"name": "Mobile Phone"
		}
	}
}

Installation

Begin by installing the package through Composer. Run the following command in your terminal:

composer require themsaid/laravel-model-transformers

Once composer is done, add the package service provider in the providers array in config/app.php

Themsaid\Transformers\TransformersServiceProvider::class

Finally publish the config file:

php artisan vendor:publish --provider="Themsaid\Transformers\TransformersServiceProvider"

That's all what we need.

Usage

Create a model transformer class by extending the AbstractTransformer class:

<?php
class CategoryTransformer extends Themsaid\Transformers\AbstractTransformer
{
    public function transformModel(Model $item)
    {
        $output = [
            'name'		=> $item->name,
            'type'		=> [
            		'key'	=> $item->type,
            		'name'	=> $item->typeName
            ],
        ];

        return $output;
    }

}

Now you can call the transformer from any controller:

<?php
return response(
	CategoryTransformer::transform( Category::find(1) )
);

You can also pass a collection and the result will be an array of transformed models:

<?php
return response(
	CategoryTransformer::transform( Category::all() )
);

Dealing with relationships

The package contains two helpful methods for dealing with relationships, the first one helps you know if a specific relation is eager-loaded:

isRelationshipLoaded()

<?php
class ProductTransformer extends AbstractTransformer
{
    public function transformModel(Model $item)
    {
        $output = array_only($item->toArray(), ['name', 'id']);

        if ($this->isRelationshipLoaded($item, 'tags')) {
            $output['tags'] = TagTransformer::transform($item->tags);
        }

        return $output;
    }
}

Now only if the tags are eager-loaded they will be presented in the $output array, this helps reminding you to eager-load when querying models with relationships.

isLoadedFromPivotTable()

This method helps you know if the model is loaded from a ManyToMany relationship, it's helpful when there are pivot data in the table and you would like to present them, example for that:

<?php
class TagTransformer extends AbstractTransformer
{
    public function transformModel(Model $item)
    {
        $output = array_only($item->toArray(), ['name', 'id']);

        if ($this->isLoadedFromPivotTable($item, 'products_tags')) {
            $output['relationship_data'] = [
                'is_active' => $item->pivot->is_active,
            ];
        }

        return $output;
    }
}

Passing options to the transformer

You may need to pass some options from the controller to the transformer, you can do that by providing an array of options to the transform() method as a second parameter:

<?php

CategoryTransformer::transform($category, ['hide_admin_id' => true])

Now from inside the CategoryTransformer you can check the options parameter:

<?php
class CategoryTransformer extends AbstractTransformer
{
    public function transformModel(Model $item)
    {
    	$output = [];
    
		if (@$this->options['hide_admin_id']) {
			unset($output['admin_id']);
		}
		
		return $output;
	}
}

Using the shorthand method

This package is shipped with a shorthand method for applying transformation for a Model or a Collection:

<?php
class SomeController{
	function getIndex(){
		$product = Product::find(1);

		return response([
			"product" => transform($product)
		]);
	}
}

Using the transform() method, the package locates the suitable transformer based on the Model or the Collection passed as the first argument.

By default it assumes that all transformers are located under the App\Transformers namespace, you can change this behaviour in the config file.

You may also pass options to the transformer as a second argument:

<?php

transform(Model::find(1), ['use_nl2br' => true])

laravel-model-transformer's People

Contributors

a-lawrence avatar omranic avatar skad0 avatar themsaid avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

laravel-model-transformer's Issues

Serializer

I know the consumer API is not really the "Laravel way", but wouldn't it be better to work on a Laravel integration of the Symfony Serializer rather than re-inventing the wheel? Actually the serializer offer you a couple more features:

  • It figures out how to serializer/deserialize your objects automatically, so no need for custom serializers. So instead of having a custom Transformer, you would just need to register the serializer instead.
  • If you need a more granular serialization, for example to display only a few properties or not allow the deserialization of some properties (user password), you can always use groups for it

I had a bit of trouble to use for my app to be honest, mainly because Eloquent models are a bit special making them hard to automatically serialize. I eventually got over it by using EloquentSerializer though.

WDYT?

Is supported with Laravel 5.3?

Hi,

I found your package very simple but yet very useful, I tried to install it on Laravel 5.3 version but it seems it has an error. Is there any version that would support Laravel 5.3?

Thanks,
Noel

I got error on my model transformer

Hello,

I have problem in using the model transformer, on the controller I called it using this line
$appointments = Appointment::where('field', condition)->get(); return Response()->json(['appointments' => AppointmentTransformer::transform( $appointments )], 200); and my model transformer is
`

class AppointmentTransformer extends Themsaid\Transformers\AbstractTransformer{
public function transformModel(Model $item)
    {
        $output = [
           "field_key" => value
        ];

        return $output;
    }

}

and I get below error:
Declaration of AppointmentTransformer::transformModel() should be compatible with Themsaid\Transformers\AbstractTransformer::transformModel(Illuminate\Database\Eloquent\Model $modelOrCollection). Is there any way how can I fixt this? Thanks :)

generate Transformer wrong


     * @param  Model  $model
     * @return array
     */
    public function transformModel(Model $model): array
    {
        return [
        ];
    }

:array
Return type declaration is available in PHP 7 only

but composer.json "require" "php" : ">=5.3.0"

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.