分析:评论--问题 评论--答案使用morphTo、morphMany

1、定义模型关系

question.php

public function comments(){
return $this->morphMany('\App\Comment','commentable');
}

answer.php

public function comments(){
return $this->morphMany('\App\Comment','commentable');
}

comment.php

public function commentable(){
return $this->morphTo();
}

//评论 属于 用户
public function user(){
return $this->belongsTo(\App\User::class);
}

2、api.php

//获取问题、答案评论
Route::get('/answer/{id}/comments','CommentsController@answer');
Route::get('/question/{id}/comments','CommentsController@question');

//评论
Route::post('/comment','CommentsController@store');

3、CommentsController.php

public function answer($id){
$answer = Answer::with('comments','comments.user')->where('id',$id)->first();
return $answer->comments;
}
public function question($id){
$question = Question::with('comments','comments.user')->where('id',$id)->first();
return $question->comments;
}
public function store(){
$model = $this->getModelNameFromType(\request('type'));
$comment = Comment::create([
'commentable_id' => \request('model'),
'commentable_type' => $model,
'user_id' => \Auth::guard('api')->user()->id,
'body' => \request('body')
]);

return $comment;
}
private function getModelNameFromType($type){
return $type === 'question' ? 'App\Question' : 'App\Answer';
}

4、vue

<template>


<div>
<a class=" is-naked delete-button"
@click="showCommentsFrom"
v-text="text"

>发表评论
</a>





<div class="modal fade" :id=dialog tabindex="-1" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button " class="close" data-dismiss="modal" aria-hidden="true">×</button>

<h4 class="modal-title">
评论列表
</h4>
</div>

<div class="modal-body">
<div v-if="comments.length > 0">

<div class="media" v-for="comment in comments">
<div class="media-left">
<a href="">
<img width="24" :src="comment.user.avatar" class="mr-3" alt="...">
</a>
</div>
<div class="media-body">
<h5 class="mt-0">{{comment.user.name}}</h5>
{{comment.body}}
</div>
</div>
</div>
</div>

<!-- Modal Actions -->
<div class="modal-footer">
<input type="text" class="form-control" v-model="body"/>
<br>
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary" @click="store">
发表评论
</button>
</div>
</div>
</div>
</div>


</div>



</template>

<script>
export default {

props:['type','model','count'],


data(){
return {
body:'',
comments: [],
}
},
computed:{
dialog(){
return 'comments-dialog-' + this.type + '-' + this.model
},
dialogId(){
return '#' + this.dialog
},
text(){
return this.count + ' 评论'
}

},

methods:{
store() {
this.$http.post('/api/comment',{'type':this.type,'model':this.model,'body':this.body}).then(response=>{
console.log(response.data);
let comment = {
user : {
name:Zhihu.name,
avatar:Zhihu.avatar
},
body: response.data.body
}
this.comments.push(comment)
this.body = '';
this.count ++;
console.log(response.data);
/*this.status = response.data.status;
setTimeout(function () {
$('#modal-send-message').modal('hide');
},2000);*/

});
},
showCommentsFrom(){
this.getComments();
$(this.dialogId).modal('show');
},
getComments(){
this.$http.get('/api/' + this.type + '/' + this.model + '/comments' ).then(response=>{
this.comments = response.data;
//console.log(this.comments);
});
}
}
}
</script>

5、view

<comments type="question" model="{{$question->id}}" count="{{$question->comments()->count()}}"></comments>

<comments type="answer" model="{{$answer->id}}" count="{{$answer->comments()->count()}}"></comments>

补充:评论表设计

public function up()
{
Schema::create('comments', function (Blueprint $table) {
$table->increments('id');
$table->unsignedInteger('user_id');
$table->text('body');
$table->unsignedInteger('commentable_id');
$table->string('commentable_type');
$table->unsignedInteger('parent_id')->nullable();
$table->smallInteger('level')->default(1);
$table->string('is_hiden',8)->default('F');

$table->timestamps();
});
}