使用Eloquent和Laravel 5在json响应中包括模型关系 [英] Include model relationships in json response using Eloquent and Laravel 5

查看:94
本文介绍了使用Eloquent和Laravel 5在json响应中包括模型关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的模型设置如下:

<?php namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Upload extends Model {

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

    /**
     * The attributes excluded from the model's JSON form.
     *
     * @var array
     */
    protected $hidden = array('id', 'user', 'created_at', 'updated_at');

    public function mime() {
        return $this->hasOne('App\Models\Mime', 'mime');
    }
}

当调用JsonSerialize()时,它返回:

{
    "serverPath": "upload/2015/06/06/21/filename.jpg",
    "filename": "filename.jpg",
    "mime": "92"
}

92使用与字符串相关联的type引用另一个表(App\Models\Mime表示)中的ID.我想用所说的字符串替换这个92.

This 92 references the id in another table (which App\Models\Mime represents) with a string, type, associated with it. I would like to replace this 92 with said string.

{
    "serverPath": "upload/2015/06/06/21/filename.jpg",
    "filename": "filename.jpg",
    "mime": "image/jpeg"
}

这怎么可能?我在Upload模型中使用protected $appends尝试了一些东西,但是我不确定我是否完全了解如何从模型内部使用/访问关系.

How is this possible? I tried some stuff with protected $appends in the Upload model, but I'm not sure I fully understand how to use/access relationships from within the model.

说明 mime 包含列idtype,而表 uploads 包含一个名为mime的整数列引用 mime

Clarification The table mimes contains columns id and type, while table uploads contains an integer column called mime that references an id in mimes

推荐答案

将一个关系命名为与表中的字段之一相同的名字不是一个好主意.尝试访问关系与访问字段时,这会导致问题(如您所知).

It is not a good idea to name a relationship the same name as one of the fields on the table. This causes issues (as you've found out) when trying to access the relationship versus accessing the field.

理想情况下,您的mime字段应重命名为mime_id.这符合Laravel的约定,并且是该字段的更准确的名称.

Ideally, your mime field should be renamed to mime_id. This conforms to Laravel's conventions, and is a more accurate name for the field.

但是,如果您不能更改字段名称,则应该更改关系的名称.

However, if you don't have the ability to change the name of the field, you should change the name of the relationship.

class Upload extends Model {
    protected $hidden = array('id', 'user', 'created_at', 'updated_at');

    public function uploadMime() {
        return $this->belongsTo('App\Models\Mime', 'mime');
    }
}

在上面的类中,关系名称现在为uploadMime.此外,该关系从hasOne更改为belongsTo.由于您的上载表具有mimes表的外键,因此上载模型属于Mime模型(而Mime模型具有One/hasMany Upload模型).

In the class above, the relationship name is now uploadMime. Additionally, the relationship was changed from a hasOne to a belongsTo. Since your uploads table has the foreign key to the mimes table, the Upload model belongsTo the Mime model (and the Mime model hasOne/hasMany Upload models).

现在,您的代码应类似于:

Now, your code should look something like:

$data = \App\Models\Upload::with('uploadMime')->findOrFail(1);
return new JsonResponse($data);

这应该使您可以输出以下内容:

This should give you output something along the lines of:

{
    "serverPath": "upload/2015/06/06/21/filename.jpg",
    "filename": "filename.jpg",
    "mime": "92",
    "uploadMime": {
        "id": 92,
        "type": "image/jpeg"
    }
}

使用$appends和属性访问器修改JSON

Modifying JSON using $appends and attribute accessors

如果您想进一步了解问题中提供的JSON输出,可以创建mimeType访问器并将其添加到$appends属性:

If you wanted to get closer to the JSON output you've provided in your question, you can create a mimeType accessor and add it to the $appends property:

class Upload extends Model {
    // hide the mime field and uploadMime data
    protected $hidden = array('id', 'user', 'created_at', 'updated_at', 'mime', 'uploadMime');

    // add the mimeType attribute to the array
    protected $appends = array('mimeType');

    // code for $this->mimeType attribute
    public function getMimeTypeAttribute($value) {
        $mimeType = null;
        if ($this->uploadMime) {
            $mimeType = $this->uploadMime->type;
        }
        return $mimeType;
    }

    public function uploadMime() {
        return $this->belongsTo('App\Models\Mime', 'mime');
    }
}

这应该使您可以输出以下内容:

This should give you output something along the lines of:

{
    "serverPath": "upload/2015/06/06/21/filename.jpg",
    "filename": "filename.jpg",
    "mimeType": "image/jpeg"
}

通过覆盖toArray()函数

Modifying JSON by overriding the toArray() function

或者,如果您确实希望JSON使用mime键,则可以直接修改toArray()方法:

Or, if you really want the JSON to use the mime key, you can modify the toArray() method directly:

class Upload extends Model {
    // hide uploadMime data, but not the mime field
    protected $hidden = array('id', 'user', 'created_at', 'updated_at', 'uploadMime');

    public function uploadMime() {
        return $this->belongsTo('App\Models\Mime', 'mime');
    }

    // override the toArray function (called by toJson)
    public function toArray() {
        // get the original array to be displayed
        $data = parent::toArray();

        // change the value of the 'mime' key
        if ($this->uploadMime) {
            $data['mime'] = $this->uploadMime->type;
        } else {
            $data['mime'] = null;
        }

        return $data;
    }
}

这应该使您可以输出以下内容:

This should give you output something along the lines of:

{
    "serverPath": "upload/2015/06/06/21/filename.jpg",
    "filename": "filename.jpg",
    "mime": "image/jpeg"
}

这篇关于使用Eloquent和Laravel 5在json响应中包括模型关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆