themsaid / laravel-model-transformers
复杂模型属性的简单转换层。
Requires
- php: >=5.3.0
- illuminate/support: ~5.1
Requires (Dev)
- orchestra/testbench: ~3.0
- phpunit/phpunit: 4.*
This package is auto-updated.
Last update: 2020-02-05 23:02:45 UTC
README
此包帮助API开发者轻松将Eloquent模型转换为可转换为JSON的数组。
以下是使用方法,假设你有一个包含以下数据的模型
{ "name": "iPhone", "type": 1 }
在这里,你使用数值来表示不同的类型,你还在模型中有一个将数值映射到字符串的修改器。
在控制器内部,我们可以将模型转换为更友好的API结构。
<?php class SomeController{ function getIndex(){ $product = Product::find(1); return response([ "product" => ProductTransformer::transform($product) ]); } }
上述代码将生成一个可能看起来像这样的JSON字符串
{ "product": { "name": "iPhone", "type": { "key": 1, "name": "Mobile Phone" } } }
安装
首先通过Composer安装包。在终端运行以下命令
composer require themsaid/laravel-model-transformers
Composer完成后,在config/app.php
中的 providers 数组中添加包服务提供者
Themsaid\Transformers\TransformersServiceProvider::class
最后发布配置文件
php artisan vendor:publish --provider="Themsaid\Transformers\TransformersServiceProvider"
这就是我们所需要的。
使用方法
通过扩展AbstractTransformer类创建一个模型转换器类
<?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; } }
现在你可以从任何控制器中调用转换器
<?php return response( CategoryTransformer::transform( Category::find(1) ) );
你也可以传递一个集合,结果将是一个转换后的模型数组
<?php return response( CategoryTransformer::transform( Category::all() ) );
处理关系
此包包含两个处理关系的有用方法,第一个帮助你知道一个特定关系是否已预加载
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; } }
现在只有当标签已预加载时,它们才会出现在 $output 数组中,这有助于在查询具有关系的模型时记住预加载。
isLoadedFromPivotTable()
此方法帮助你知道模型是否是从多对多关系加载的,当表中存在枢纽数据并且你希望展示它们时,这很有用。
<?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; } }
向转换器传递选项
你可能需要从控制器向转换器传递一些选项,你可以通过将选项数组作为 transform()
方法的第二个参数提供来实现。
<?php CategoryTransformer::transform($category, ['hide_admin_id' => true])
现在,从CategoryTransformer内部可以检查选项参数
<?php class CategoryTransformer extends AbstractTransformer { public function transformModel(Model $item) { $output = []; if (@$this->options['hide_admin_id']) { unset($output['admin_id']); } return $output; } }
使用简写方法
此包包含一个简写方法,用于对模型或集合应用转换
<?php class SomeController{ function getIndex(){ $product = Product::find(1); return response([ "product" => transform($product) ]); } }
使用 transform()
方法,该包根据作为第一个参数传递的模型或集合查找合适的转换器。
默认情况下,它假定所有转换器都位于 App\Transformers
命名空间下,你可以在配置文件中更改此行为。
您还可以将选项作为第二个参数传递给转换器
<?php transform(Model::find(1), ['use_nl2br' => true])