我们建的model都是单表操作,彼此之间无法互相访问,这里就是解决跨表查询问题。
例如点赞功能的实现:回答和用户是多对多的关系
建立连接表,规则就是表名称首字母排序
php artisan make:migration create_table_anwser_user --create=anwser_user
migrations完善代码
public function up()
{
Schema::create('answer_user', function (Blueprint $table) {
$table->increments('id');
$table->unsignedInteger('user_id');
$table->unsignedInteger('answer_id');
$table->unsignedSmallInteger('vote');
$table->timestamps();
$table->foreign('user_id')->references('id')->on(' users ');
$table->foreign('answer_id')->references('id')->on('answers');
$table->unique(['user_id','answer_id','vote']);
});
}
//model Anwser.php
多对多关系 :
public function users() { return $this ->belongsToMany('App\User') ->withPivot('vote') //pivot属性访问中间表字段,要访问必须先关联 ->withTimestamps(); }
vote方法:
$answer = $this->find(rq('id'));
$vote = rq('vote');
if($vote!=1&&$vote!=2&&$vote!=3){
return ['status' => 0,' msg ' => 'invalid vote'];
}
//每次操作先删除
$answer ->users()
->newPivotStatement()
->where('user_id',session('user_id'))
->where('answer_id',rq('id'))
->delete();
if($vote == 3){ //仅取消投票
return ['status' => 1];
}
//把关系连接起来,并执行投票
$answer ->users() ->attach(session('user_id'),['vote'=>$vote]);
补充:取数据
$vote = $answer ->users() ->newPivotStatement() ->where('user_id',session('user_id')) ->where('answer_id',rq('id')) ->first(); //限制为一条,也可以count()
如何看之前的后端效果 :
创建控制器CommonController
php artisan make:controller CommonController
生成路径为app/http/CommonController.php,增加代码
public function timeline()
{
list($limit,$skip) = paginate(rq('page'),rq('limit')); //自定的分页函数
//获取问题数据
$questions = question_ins()
->with('user')
->limit($limit)
->skip($skip)
->orderBy('created_at','desc')
->get();
//获取回复数据
$answers = answer_ins()
->with('question')
->with('users')
->with('user')
->limit($limit)
->skip($skip)
->orderBy('created_at','desc')
->get();
//合并数据
$data = $questions-> merge ($answers);
//按照时间排序
$data = $data->sortByDesc(function($item){
return $item->created_at;
});
$data = $data->values()->all(); //去除laraval系统自编号
return ['status' => 1,'data' =>$data];
}
Route.php里调用
Route::any('api/timeline','CommonController@timeline');