我有一个模型设置:
<?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
引用另一个表(App\Models\Mime
表示的)中的id,其中包含与之关联的字符串type
。我想用这个字符串替换这个92
。
{
"serverPath": "upload/2015/06/06/21/filename.jpg",
"filename": "filename.jpg",
"mime": "image/jpeg"
}
这怎么可能?我在protected $appends
模型中尝试了Upload
的一些内容,但我不确定我是否完全理解如何在模型中使用/访问关系。
澄清表 mimes 包含列id
和type
,而表上传包含一个名为整数的列引用 mimes
mime
答案 0 :(得分:44)
将关系命名为与表中某个字段相同的名称并不是一个好主意。这会导致在尝试访问关系与访问该字段时出现问题(正如您已经发现的那样)。
理想情况下,您的mime
字段应重命名为mime_id
。这符合Laravel的惯例,并且是该领域更准确的名称。
但是,如果您无法更改字段名称,则应更改关系名称。
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上载模型)。
现在,您的代码应该类似于:
$data = \App\Models\Upload::with('uploadMime')->findOrFail(1);
return new JsonResponse($data);
这应该可以为您输出以下内容:
{
"serverPath": "upload/2015/06/06/21/filename.jpg",
"filename": "filename.jpg",
"mime": "92",
"uploadMime": {
"id": 92,
"type": "image/jpeg"
}
}
使用$appends
和属性访问者修改JSON
如果您希望更接近问题中提供的JSON输出,可以创建mimeType
访问者并将其添加到$appends
媒体资源中:
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');
}
}
这应该可以为您输出以下内容:
{
"serverPath": "upload/2015/06/06/21/filename.jpg",
"filename": "filename.jpg",
"mimeType": "image/jpeg"
}
通过覆盖toArray()
功能
或者,如果您确实希望JSON使用mime
密钥,则可以直接修改toArray()
方法:
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;
}
}
这应该可以为您输出以下内容:
{
"serverPath": "upload/2015/06/06/21/filename.jpg",
"filename": "filename.jpg",
"mime": "image/jpeg"
}
答案 1 :(得分:1)
好的,我相信这就是你要找的......
Upload.php (此处无变化)
<?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');
}
}
然后你有你的Mime模型
<强> Mime.php 强>
<?php namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Mime extends Model {
/**
* The database table used by the model.
*
* @var string
*/
protected $table = 'mimes';
}
如果您为测试执行此操作,我相信您应该看到类型
<强> routes.php文件强>
Route::get('test', function() {
$upload = \Upload::with('mime')->first();
// return $upload //here would return it as JSON I'm pretty sure!
return $upload->mime->type;
});
检查文档以获取有关预先加载的更多详细信息:http://laravel.com/docs/5.0/eloquent#eager-loading