モデルのセットアップは次のとおりです。
_<?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
_を上記の文字列に置き換えたいと思います。
_{
"serverPath": "upload/2015/06/06/21/filename.jpg",
"filename": "filename.jpg",
"mime": "image/jpeg"
}
_
これはどのように可能ですか? Upload
モデルで_protected $appends
_を使っていくつか試しましたが、モデル内からリレーションシップを使用/アクセスする方法を完全に理解しているかどうかはわかりません。
明確化テーブルmimesには列id
およびtype
が含まれますが、テーブルuploadsmimesのIDを参照するmime
という整数列が含まれています
リレーションシップにテーブルのフィールドの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テーブルへの外部キーがあるため、UploadモデルはMimeモデル(およびMimeモデルhasOne/hasMany Uploadモデル)に属します。
これで、コードは次のようになります。
_$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を変更する
または、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"
}
_
さて、これがあなたが探しているものだと思います...
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