我有个视频列表,关联了好几个表,已解决分享
视频表video,
标题写在common表。
属于某个专辑,album_id
视频文字内容,用另一个表video_data记录
这几个表的关系:
common表, 字段: common_id,title,category_id,model,tag
其中,model的值可以是video,article 等。
video表,字段:video_id, album_id, speech_data,common_id
video_data表,字段:video_id, content
album表, 字段:album_id, title,
现在需要把视频表的详情显示出来。
// app\Models\Video 文件
protected $primaryKey = 'video_id';
.
public function Common()
{
return $this->belongsTo(EduCommon::class,'common_id','common_id');
}
// 写成video_data会报错。
public function videoData(){
return $this->hasOne(VideoData::class,'video_id','video_id');
}
public function scopeRecent($query)
{
$query->orderBy('created_at', 'desc');
}
public function scopeRecentUpdated($query)
{
$query->orderBy('updated_at', 'desc');
}
public function scopeWithOrder($query, $order)
{
switch ($order) {
case 'recent':
$query->recent();
break;
default:
$query->recentUpdated();
break;
}
}
// app\Models\VideoData 文件
protected $primaryKey = 'video_id';
.
public function video(){
return $this->belongsTo(Video::class,'video_id','video_id');
}
// app\Models\Common 文件
public function video()
{
return $this->hasOne(Video::class,'common_id','common_id');
}
// VideoResource 文件
public function toArray($request)
{
$data = parent::toArray($request);
$data['common'] = new CommonResource($this->whenLoaded('common'));
$data['video_data'] = new VideoDataResource($this->whenLoaded('videoData'));
return $data;
}
// VideoController 文件
use Spatie\QueryBuilder\AllowedFilter;
use Spatie\QueryBuilder\QueryBuilder;
.
.
public function index(){
$videos = QueryBuilder::for(Video::class)
->allowedIncludes('common','video_data','album')
->allowedFilters([
AllowedFilter::scope('withOrder')->default('recentUpdated'),
])
->paginate();
return VideoResource::collection($videos);
}
public function show($video_id)
{
$video = QueryBuilder::for(Video::class)
->allowedIncludes('common','video_data','album')
->findOrFail($video_id);
return new VideoResource($video);
}
// routes/api.php
// 视频列表、详情
Route::resource('video', 'VideoController')->only([ 'index','show']);
接口:
列表:
http://{{host}}/api/v1/video?include=edu_common,video_data,album&filter[withOrder]=recentUpdated
详情
http://{{host}}/api/v1/video/:video_id?include=edu_common,video_data,album
由于一开始展示的是common列表,此时并不能知道video_id
这次我在Common控制器里写了这一个方法。不过,感觉有些复杂。不知有没有更好的写法。
public function detail(EduCommon $common, $model)
{
$map['common_id'] = $common->common_id;
switch($model){
case 'article':
$info = Article::where($map)->first();
$detail = QueryBuilder::for(Article::class)
->findOrFail($info->article_id);
return new VideoResource($detail);
break; case 'video':
$info = Video::where($map)->first();
$detail = QueryBuilder::for(Video::class)
->allowedIncludes('video_data','album')
->findOrFail($info->video_id);
return new VideoResource($detail);
break; case 'audio':
$info = Audio::where($map)->first();
$detail = QueryBuilder::for(Audio::class)
->allowedIncludes('album')
->findOrFail($info->audio_id);
return new VideoResource($detail);
break; }
}
接口为:
http://{{host}}/api/v1/common/:common_id/:model?include=album
谢谢您耐心的阅读到结尾。
推荐文章: