Laravel - Fractal - 在变换器文件中使用Find() - 它是正确的还是可以更高效地完成?

时间:2015-06-05 07:54:52

标签: php api laravel laravel-5

所以,我正在使用Laravel 5和Fractal为我的数据输出添加演示和转换层,并想知道我在下面做的是正确的还是过度的。

我有用户表和收藏夹表,我希望我的JSON输出如下:

注意:密切关注嵌套数据中的 profile_id id 。我基本上想要我的最爱,并且在那些我喜欢的用户详细信息(来自用户表)中。

下面,我赞成了profile_id 404,他的详细信息(来自用户表)也是嵌套的。

"data": [
    {
        "id": 15,
        "user_id": 231,
        "profile_id": 404, <------------------------ HERE
        "created_date": "2013-04-10 21:35:28",
        "user": {
            "data": {
                "id": 404, <------------------------ HERE
                "username": "hugeheart12",
                "has_photo": 1
            }
        }
    },
    {
        "id": 64,
        "user_id": 231,
        "profile_id": 1085, <------------------------ HERE
        "created_date": "2013-06-17 08:14:02",
        "user": {
            "data": {
                "id": 1085, <------------------------ HERE
                "username": "snowbird37",
                "has_photo": 1
            }
        }
    }

用户
id(PK)
命名
用户名
电子邮件
CREATED_DATE

收藏夹
ID
USER_ID
PROFILE_ID
CREATED_DATE

用户模型

<?php namespace App;

use Illuminate\Auth\Authenticatable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Auth\Passwords\CanResetPassword;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;
use Illuminate\Support\Facades\DB;


class User extends Model implements AuthenticatableContract, CanResetPasswordContract {

use Authenticatable, CanResetPassword;

/**
 * The database table used by the model.
 *
 * @var string
 */
protected $table = 'users';

public function favourites()
{
    return $this->hasMany('App\Favourites', 'profile_id', 'id');
}

public function photos()
{
    return $this->hasMany('App\Photos', 'user_id', 'id');
}

最喜欢的型号

<?php namespace App;

use Illuminate\Database\Eloquent\Model;

class Favourites extends Model {

    protected $table = 'favourite';

    public function user()
    {
        return $this->belongsTo('App\User', 'from', 'id');
    }
}

这就是我在控制器中所拥有的:

$favourites = Favourites::with('user')->where('profile_id', '=', 231)->get();  

$resource = new Fractal\Resource\Collection($favourites , new FavouriteTransformer());

return $this->respond(
    $this->fractal->createData($resource)->toArray()
);

FavouriteTransformer

<?php
namespace App\Mmh\Transformer;

use App\Favourites;
use League\Fractal;


class FavouriteTransformer  extends Fractal\TransformerAbstract
{

protected $defaultIncludes = [
    'user'
];


public function transform(Favourites $favourites)
{
    return [
        'id'           => (int)$favourites->id,
        'user_id'         => (int)$favourites->user_id,
        'profile_id'           => (int)$favourites->profile_id,
        'created_date' => $favourites->created_date,
    ];
}

public function includeUser( Favourites $favourites )
{        
    return $this->item( 
        $favourites->user->find($favourites->profile_id), new UserTransformer 
    );
}

}

查看最后一个返回$ this-&gt; item( $ favourites-&gt; user-&gt; find($ favourites-&gt; profile_id),新的UserTransformer);

上面的所有代码都给了我上面的JSON,但有没有办法以更好的方式做到这一点,或者我这样做的方式是否正确?有些东西告诉我必须有一个更好的方法来做这个,而不是查询每个项目的数据库,但我不知道如何。

感谢您的阅读。

1 个答案:

答案 0 :(得分:0)

您已经急切加载user中的controller,因此我认为您无需再次userfavourites FavouriteTransformer }}。 您只需使用此选项即可包含user

return $this->item( 
        $favourites->user, new UserTransformer 
    );

Fractal会看到,user已经存在,所以它不会调用db query来获取数据。