Ответ 1
Неплохо было бы назвать отношения такими же именами, как одно из полей таблицы. Это вызывает проблемы (как вы выяснили) при попытке получить доступ к зависимости от доступа к полю.
В идеале ваше поле 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 имеет одну или несколько моделей загрузки).
Теперь ваш код должен выглядеть примерно так:
$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"
}
}
Изменение JSON с использованием $appends
и аксессуаров атрибутов
Если вы хотите приблизиться к выходу 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"
}
Изменение JSON путем переопределения функции 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"
}