我有个视频列表,关联了好几个表,已解决分享

视频表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

谢谢您耐心的阅读到结尾。

《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!