Laravel Vuejs 实战:开发知乎 (18-19)用户关注问题

1.添加授权策略

为了让问题只能被登录用户关注  且用户关注与未关注的区别不同显示

提示:使用policy

  1 php artisan make:policy QuestionPolicy

QuestionPolicy文件:

  1 <?php
  2 
  3 namespace App\Policies;
  4 
  5 use App\Models\Question;
  6 use App\User;
  7 use Illuminate\Auth\Access\HandlesAuthorization;
  8 
  9 class QuestionPolicy
 10 {
 11     use HandlesAuthorization;
 12 
 13     /**
 14      * Create a new policy instance.
 15      *
 16      * @return void
 17      */
 18     public function __construct()
 19     {
 20         //
 21 
 22     }
 23 
 24 
 25     /**
 26      * 判断用户是否有权编辑更新问题
 27      * @param User $user
 28      * @param Question $question
 29      * @return bool
 30      */
 31     public function update(User $user, Question $question)
 32     {
 33         return $user->id === $question->user_id;
 34     }
 35 
 36 
 37     /**
 38      * 判断用户是否有权删除问题
 39      * @param User $user
 40      * @param Question $question
 41      * @return bool
 42      */
 43     public function destroy(User $user, Question $question)
 44     {
 45         return $user->id === $question->user_id;
 46     }
 47 
 48 
 49     /** 用户是否可以关注问题,未登录不行,关注了不行
 50      * @param User $user
 51      * @param Question $question
 52      * @return bool
 53      */
 54     public function follow(User $user, Question $question)
 55     {
 56         return auth()->user()->id === $user->id && !$user->followQuestions->contains('id', $question->id);
 57     }
 58 }
 59 
 60 
QuestionPolicy.php

修改show页面对关注后和未关注的不同显示

  1 @extends('layouts.app')
  2 @section('content')
  3     <div class="container">
  4         <div class="row">
  5             <div class="col-md-8 col-md offset-1">
  6                 {{--问题--}}
  7                 <div class="card">
  8                     <div class="card-header">
  9                         {{ $question->title }}
 10 
 11                         @foreach(['success','warning','danger'] as $info)
 12                             @if(session()->has($info))
 13                                 <div class="alert alert-{{$info}}">{{ session()->get($info) }}</div>
 14                             @endif
 15                         @endforeach
 16 
 17                         @can('update',$question)
 18                             <a href="{{ route('questions.edit',$question) }}" class="btn btn-warning">编辑</a>
 19                         @endcan
 20 
 21                         @can('destroy',$question)
 22                             <form action="{{ route('questions.destroy',$question) }}" method="post">
 23                                 @csrf
 24                                 @method('DELETE')
 25                                 <button type="submit" class="btn btn-danger">删除</button>
 26                             </form>
 27                         @endcan
 28 
 29                         @forelse($question->topics as $topic)
 30                             <button class="btn btn-secondary float-md-right m-1">{{ $topic->name }}</button>
 31                         @empty
 32                             <p class="text text-warning float-md-right"> "No Topics"</p>
 33                         @endforelse
 34 
 35                         <p class="text text-info float-md-right"> 已有{{ count($question->answers) }}个回答</p>
 36 
 37                     </div>
 38                     <div class="card-body">
 39                         {!! $question->content !!}
 40                     </div>
 41                 </div>
 42 
 43 
 44                 {{--回答提交form--}}
 45                 {{--只有登录用户可以提交回答--}}
 46                 @if(auth()->check())
 47                     <div class="card mt-2">
 48                         <div class="card-header">
 49                             提交回答
 50                         </div>
 51                         <div class="card-body">
 52                             <form action="{{ route('answers.store',$question) }}" method="post">
 53                             @csrf
 54                             <!-- 回答编辑器容器 -->
 55                                 <script id="container" name="content" type="text/plain"
 56                                         style="width: 100%;height: 200px">{!! old('content') !!}</script>
 57                                 <p class="text text-danger"> @error('content') {{ $message }} @enderror </p>
 58                                 <!--提交按钮-->
 59                                 <button type="submit" class="btn btn-primary float-md-right mt-2">提交回答</button>
 60                             </form>
 61                         </div>
 62                     </div>
 63                 @else
 64                     {{--显示请登录--}}
 65                     <a href="{{ route('login') }}" class="btn btn-success btn-block mt-4">登录提交答案</a>
 66                 @endif
 67                 {{--展示答案--}}
 68                 @forelse($question->answers as $answer)
 69                     <div class="card mt-4">
 70                         <div class="card-header">
 71                             <div class="float-left">
 72                                 <img src="{{ $answer->user->avatar }}" class="img-thumbnail imgWrap"
 73                                      style="height: 50px" alt="{{ $answer->user->name }}">
 74                                 <span class="text text-info">{{ $answer->user->name }}</span>
 75                             </div>
 76                             <span class="float-right text text-info m-auto">{{ $answer->updated_at }}</span>
 77                         </div>
 78 
 79                         <div class="card-body">
 80                             {!!  $answer->content  !!}
 81                         </div>
 82                     </div>
 83 
 84                 @empty
 85 
 86                 @endforelse
 87             </div>
 88 
 89             <div class="col-md-3">
 90                 <div class="card">
 91                     <div class="card-header">
 92                         <h2> {{ $question->followers_count }}</h2>
 93                         <span>关注者</span>
 94                     </div>
 95 
 96                     <div class="card-body">
 97                         @if(auth()->check())
 98                             {{--                        如果用户已经关注过,则显示取消关注按钮--}}
 99                             @can('follow',$question)
100                                 <a href="{{ route('questions.follow',$question) }}"
101                                    class="btn btn-primary btn-block">点击关注</a>
102                             @else
103                                 <a href="{{ route('questions.follow',$question) }}"
104                                    class="btn btn-danger btn-block">取消关注</a>
105                             @endcan
106                         @else
107                             <a href="{{ route('questions.follow',$question) }}"
108                                class="btn btn-primary btn-block">点击关注</a>
109 
110                         @endif
111                     </div>
112 
113                 </div>
114             </div>
115         </div>
116     </div>
117 @endsection
118 @section('footer-js')
119     @include('questions._footer_js')
120 @endsection
121 
122 
show.blade.php

修改跳转位置:

在RouteServiceProvider中添加:

  1 public const QUESTION = '/questions';

LoginController中:

将RouteServiceProvider::Home 改为 RouteServiceProvider::QUESTION

RedirectIfAuthenticated中:

将RouteServiceProvider::Home 改为 RouteServiceProvider::QUESTION

2. 添加一张表用于管理用户关注问题,多对多 一个用户可以关注多个问题,一个问题可以被多个用户关注

可以参考follow系统原理:

Laravel 6 | Follow Unfollow System Example From Scratch

Laravel Eloquent followers relationship

【之前创建的表是用户创建问题 及 tags与questions之间的表】

  1 php artisan make:migration create_users_questions_table

migration文件代码:

  1 <?php
  2 
  3 use Illuminate\Database\Migrations\Migration;
  4 use Illuminate\Database\Schema\Blueprint;
  5 use Illuminate\Support\Facades\Schema;
  6 
  7 class CreateUsersQuestionsTable extends Migration
  8 {
  9     /**
 10      * Run the migrations.
 11      *
 12      * @return void
 13      */
 14     public function up()
 15     {
 16         //用户关注的问题 与 问题下关注的用户 的表
 17         Schema::create('users_questions', function (Blueprint $table) {
 18             $table->bigIncrements('id');
 19             $table->unsignedBigInteger('user_id')->index();
 20             $table->unsignedBigInteger('question_id')->index();
 21             $table->timestamps();
 22         });
 23     }
 24 
 25     /**
 26      * Reverse the migrations.
 27      *
 28      * @return void
 29      */
 30     public function down()
 31     {
 32         Schema::dropIfExists('users_questions');
 33     }
 34 }
 35 
 36 
_create_users_questions_table.php

然后:

  1 php artisan migrate

model关联关系:

Question.php

  1 <?php
  2 
  3 namespace App\Models;
  4 
  5 use App\Answer;
  6 use App\Topic;
  7 use App\User;
  8 use Illuminate\Database\Eloquent\Model;
  9 use Illuminate\Database\Eloquent\SoftDeletes;
 10 
 11 class Question extends Model
 12 {
 13     //软删除 添加
 14     use SoftDeletes;
 15     //
 16     protected $fillable = ['title', 'content', 'user_id'];
 17     //支持软删除 添加
 18     protected $dates = ['deleted_at'];
 19 
 20     public function topics()
 21     {
 22         return $this->belongsToMany(
 23             Topic::class,
 24             'questions_topics' //表名我设置的是questions_topics,可能不是系统自动解析的question_topic
 25         )->withTimestamps();//withTimestamps操作questions_topics表中create_at及updated_at字段的
 26     }
 27 
 28     public function user()
 29     {
 30         return $this->belongsTo(User::class);
 31     }
 32 
 33     /** scope+请求名命名的
 34      * @return bool
 35      */
 36     public function scopePublished($query)
 37     {
 38         return $query->where('is_hidden', 'F');//等于F表示不隐藏
 39     }
 40 
 41 
 42     /** 一个问题有多个回答
 43      * @return \Illuminate\Database\Eloquent\Relations\HasMany
 44      */
 45     public function answers()
 46     {
 47         return $this->hasMany(Answer::class);
 48     }
 49 
 50 
 51     public function followUsers()
 52     {
 53         //默认表名 可以不设置后面三个参数,自定义表名需要设置
 54         return $this->belongsToMany(Question::class, 'users_questions', 'user_id', 'question_id');
 55     }
 56 
 57 }
 58 
Question.php

User.php

  1 <?php
  2 
  3 namespace App;
  4 
  5 use App\Models\Question;
  6 use Illuminate\Contracts\Auth\MustVerifyEmail;
  7 use Illuminate\Database\Eloquent\SoftDeletes;
  8 use Illuminate\Foundation\Auth\User as Authenticatable;
  9 use Illuminate\Notifications\Notifiable;
 10 
 11 class User extends Authenticatable implements MustVerifyEmail
 12 {
 13     use Notifiable;
 14     #region 支持软删除
 15     use SoftDeletes;
 16     protected $dates = ['deleted_at'];
 17     #endregion
 18     /**
 19      * The attributes that are mass assignable.
 20      *
 21      * @var array
 22      */
 23     protected $fillable = [
 24         'name', 'email', 'password', 'avatar', 'activation_token'
 25     ];
 26 
 27     /**
 28      * The attributes that should be hidden for arrays.
 29      *
 30      * @var array
 31      */
 32     protected $hidden = [
 33         'password', 'remember_token',
 34     ];
 35 
 36     /**
 37      * The attributes that should be cast to native types.
 38      *
 39      * @var array
 40      */
 41     protected $casts = [
 42         'email_verified_at' => 'datetime',
 43     ];
 44 
 45 
 46     /**添加用户模型和问题模型的模型关联
 47      * @return \Illuminate\Database\Eloquent\Relations\HasMany
 48      */
 49     public function questions()
 50     {
 51         return $this->hasMany(Question::class);
 52     }
 53 
 54 
 55     /** 添加用户模型和回答模型的模型关联 一个用户可以有多个回答
 56      * @return \Illuminate\Database\Eloquent\Relations\HasMany
 57      */
 58     public function answers()
 59     {
 60         return $this->hasMany(Answer::class);
 61     }
 62 
 63 
 64     public function followQuestions()
 65     {
 66         //默认表名 可以不设置后面三个参数,自定义表名需要设置
 67         return $this->belongsToMany(Question::class, 'users_questions', 'question_id', 'user_id');
 68     }
 69 }
 70 
 71 
User.php

QuestionController.php

  1 <?php
  2 
  3 namespace App\Http\Controllers;
  4 
  5 use App\Http\Requests\QuestionStoreRequest;
  6 use App\Models\Question;
  7 use App\Repositories\QuestionRepository;
  8 
  9 
 10 class QuestionController extends Controller
 11 {
 12 
 13     /**
 14      * @var QuestionRepository
 15      */
 16     private $questionRepository;
 17 
 18     public function __construct(QuestionRepository $questionRepository)
 19     {
 20         $this->middleware(
 21             'auth',
 22             [
 23                 'except' =>
 24                     [
 25                         'index',
 26                         'show',
 27                     ]//非注册用户只能查看不能编辑添加更改删除
 28             ]
 29         );
 30 
 31         $this->questionRepository = $questionRepository;
 32     }
 33 
 34 
 35     /** Display a listing of the resource.
 36      * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
 37      */
 38     public function index()
 39     {
 40         //
 41         $questions = $this->questionRepository->getQuestionPublished();
 42         return view('questions.index', compact('questions'));
 43     }
 44 
 45 
 46     /**
 47      * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
 48      */
 49     public function create()
 50     {
 51         //
 52         return view('questions.create');
 53     }
 54 
 55 
 56     /**
 57      * @param QuestionStoreRequest $request
 58      * @return \Illuminate\Http\RedirectResponse
 59      */
 60     public function store(QuestionStoreRequest $request)//依赖注入QuestionStoreRequest实例
 61     {
 62         //
 63 //        $data = $request->validate([
 64 //            'title' => 'required|min:8',
 65 //            'content' => 'required|min:28',
 66 //        ]);
 67         //存储topics
 68         $topics = $this->questionRepository->normalizeTopics($request->get('topics'));
 69         //初始化question要用到的数据
 70         $data = $request->all();
 71         $data['user_id'] = auth()->user()->id;
 72 
 73 //        $question=Question::create($data); 被下方代码取代
 74         $question = $this->questionRepository->create($data);
 75 
 76         //使用我们再question model里面添加的topics方法获得 topics关联,再使用attach方法
 77         $question->topics()->attach($topics);
 78 
 79         return redirect()->route('questions.show', $question);
 80     }
 81 
 82 
 83     /**
 84      * @param Question $question
 85      * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
 86      */
 87     public function show(Question $question)
 88     {
 89         //使用关系关联加载,with方法会将分类之下的主题一起查询出来,而且不会出现N+1影响性能的问题
 90         $question->with('topics')->get();
 91         //使用关系关联加载,with方法会将分类之下的回答一起查询出来,而且不会出现N+1影响性能的问题
 92         $question->with('answers')->get();
 93 
 94         return view('questions.show', compact('question'));
 95     }
 96 
 97 
 98     /**判断权限 返回视图
 99      * @param Question $question
100      * @return \Illuminate\Contracts\View\Factory|\Illuminate\Http\RedirectResponse|\Illuminate\View\View
101      */
102     public function edit(Question $question)
103     {
104         if (auth()->user()->can('update', $question)) //判断当前用户是否有权编辑更新该question实例
105         {
106             //返回编辑视图
107             return view('questions.edit', compact('question'));
108         } else {
109             //返回警告 没有权限
110             return redirect()->back()->with('warning', '你不能编辑不属于你的问题!');
111         }
112     }
113 
114 
115     /** Update the specified resource in storage.
116      * @param QuestionStoreRequest $questionStoreRequest
117      * @param Question $question
118      * @return \Illuminate\Http\RedirectResponse
119      */
120     public function update(QuestionStoreRequest $questionStoreRequest, Question $question)
121     {
122         //更新前 判断下权限
123         if (!(auth()->user()->can('update', $question))) {
124             //返回警告 没有权限
125             return redirect()->back()->with('warning', '你不能编辑不属于你的问题!');
126         }
127         //取得更新的字段 使用Eloquent提供的update方法执行问题更新
128         $question->update([
129             'title' => $questionStoreRequest->get('title'),
130             'content' => $questionStoreRequest->get('content'),
131         ]);
132 
133 
134         //topics的操作这时候看起来有点臃肿 可以使用TopicController来管理,暂时省略
135         //存储topics
136         $topics = $this->questionRepository->normalizeTopics($questionStoreRequest->get('topics'));
137         //使用我们再question model里面添加的topics方法获得 topics关联,
138         //再使用sync方法同步tag 【删除的会被删除掉,没删除的就保留,新的就增加】
139         $question->topics()->sync($topics);
140 
141         //更新完成,跳转回去
142         return redirect()->back();
143     }
144 
145 
146     /**Remove the specified resource from storage.
147      * @param Question $question
148      * @return \Illuminate\Http\RedirectResponse
149      * @throws \Exception
150      */
151     public function destroy(Question $question)
152     {
153         //
154         if (auth()->user()->can('destroy', $question)) {
155             $question->delete();
156             return redirect()->route('questions.index')->with('success', "删除成功!");
157         }
158         return redirect()->back()->with('danger', "你不能删除不属于你的问题!");
159     }
160 
161 
162     public function follow(Question $question)
163     {
164         if (auth()->user()->can('follow', $question)) //通过QuestionPolicy的follow方法判断用户是否可以关注问题
165         {
166             //同步记录
167             auth()->user()->followQuestions()->sync($question);
168             //关注数加1
169             $question->increment('followers_count');
170             $message = "关注";
171         } else {
172             //取消记录
173             auth()->user()->followQuestions()->detach($question);
174             //关注数减1
175             $question->decrement('followers_count');
176             $message = "取关";
177         }
178 
179         return redirect()->back()->with('success', $message . '成功!');
180     }
181 
182 }
183 
QuestionController.php



3.优化:

关注 使用toggle方法tags 与 questions 适合用sync detach attach方法 具体参考官方文档: 切换关联laravel toggle方法

  1 <?php
  2 
  3 namespace App\Http\Controllers;
  4 
  5 use App\Http\Requests\QuestionStoreRequest;
  6 use App\Models\Question;
  7 use App\Repositories\QuestionRepository;
  8 
  9 
 10 class QuestionController extends Controller
 11 {
 12 
 13     /**
 14      * @var QuestionRepository
 15      */
 16     private $questionRepository;
 17 
 18     public function __construct(QuestionRepository $questionRepository)
 19     {
 20         $this->middleware(
 21             'auth',
 22             [
 23                 'except' =>
 24                     [
 25                         'index',
 26                         'show',
 27                     ]//非注册用户只能查看不能编辑添加更改删除
 28             ]
 29         );
 30 
 31         $this->questionRepository = $questionRepository;
 32     }
 33 
 34 
 35     /** Display a listing of the resource.
 36      * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
 37      */
 38     public function index()
 39     {
 40         //
 41         $questions = $this->questionRepository->getQuestionPublished();
 42         return view('questions.index', compact('questions'));
 43     }
 44 
 45 
 46     /**
 47      * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
 48      */
 49     public function create()
 50     {
 51         //
 52         return view('questions.create');
 53     }
 54 
 55 
 56     /**
 57      * @param QuestionStoreRequest $request
 58      * @return \Illuminate\Http\RedirectResponse
 59      */
 60     public function store(QuestionStoreRequest $request)//依赖注入QuestionStoreRequest实例
 61     {
 62         //
 63 //        $data = $request->validate([
 64 //            'title' => 'required|min:8',
 65 //            'content' => 'required|min:28',
 66 //        ]);
 67         //存储topics
 68         $topics = $this->questionRepository->normalizeTopics($request->get('topics'));
 69         //初始化question要用到的数据
 70         $data = $request->all();
 71         $data['user_id'] = auth()->user()->id;
 72 
 73 //        $question=Question::create($data); 被下方代码取代
 74         $question = $this->questionRepository->create($data);
 75 
 76         //使用我们再question model里面添加的topics方法获得 topics关联,再使用attach方法
 77         $question->topics()->attach($topics);
 78 
 79         return redirect()->route('questions.show', $question);
 80     }
 81 
 82 
 83     /**
 84      * @param Question $question
 85      * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
 86      */
 87     public function show(Question $question)
 88     {
 89         //使用关系关联加载,with方法会将分类之下的主题一起查询出来,而且不会出现N+1影响性能的问题
 90         $question->with('topics')->get();
 91         //使用关系关联加载,with方法会将分类之下的回答一起查询出来,而且不会出现N+1影响性能的问题
 92         $question->with('answers')->get();
 93 
 94         return view('questions.show', compact('question'));
 95     }
 96 
 97 
 98     /**判断权限 返回视图
 99      * @param Question $question
100      * @return \Illuminate\Contracts\View\Factory|\Illuminate\Http\RedirectResponse|\Illuminate\View\View
101      */
102     public function edit(Question $question)
103     {
104         if (auth()->user()->can('update', $question)) //判断当前用户是否有权编辑更新该question实例
105         {
106             //返回编辑视图
107             return view('questions.edit', compact('question'));
108         } else {
109             //返回警告 没有权限
110             return redirect()->back()->with('warning', '你不能编辑不属于你的问题!');
111         }
112     }
113 
114 
115     /** Update the specified resource in storage.
116      * @param QuestionStoreRequest $questionStoreRequest
117      * @param Question $question
118      * @return \Illuminate\Http\RedirectResponse
119      */
120     public function update(QuestionStoreRequest $questionStoreRequest, Question $question)
121     {
122         //更新前 判断下权限
123         if (!(auth()->user()->can('update', $question))) {
124             //返回警告 没有权限
125             return redirect()->back()->with('warning', '你不能编辑不属于你的问题!');
126         }
127         //取得更新的字段 使用Eloquent提供的update方法执行问题更新
128         $question->update([
129             'title' => $questionStoreRequest->get('title'),
130             'content' => $questionStoreRequest->get('content'),
131         ]);
132 
133 
134         //topics的操作这时候看起来有点臃肿 可以使用TopicController来管理,暂时省略
135         //存储topics
136         $topics = $this->questionRepository->normalizeTopics($questionStoreRequest->get('topics'));
137         //使用我们再question model里面添加的topics方法获得 topics关联,
138         //再使用sync方法同步tag 【删除的会被删除掉,没删除的就保留,新的就增加】
139         $question->topics()->sync($topics);
140 
141         //更新完成,跳转回去
142         return redirect()->back();
143     }
144 
145 
146     /**Remove the specified resource from storage.
147      * @param Question $question
148      * @return \Illuminate\Http\RedirectResponse
149      * @throws \Exception
150      */
151     public function destroy(Question $question)
152     {
153         //
154         if (auth()->user()->can('destroy', $question)) {
155             $question->delete();
156             return redirect()->route('questions.index')->with('success', "删除成功!");
157         }
158         return redirect()->back()->with('danger', "你不能删除不属于你的问题!");
159     }
160 
161 
162     public function follow(Question $question)
163     {
164         if (auth()->user()->can('follow', $question)) //通过QuestionPolicy的follow方法判断用户是否可以关注问题
165         {
166             $message = "关注";
167         } else {
168             $message = "取关";
169         }
170         //同步记录
171         auth()->user()->followQuestions()->toggle($question);
172         $question->followers_count = $question->followUsers()->count();
173         $question->save();
174         return redirect()->back()->with('success', $message . '成功!');
175     }
176 
177 }
178 
179 
QuestionController.php

更新模型关系,加时间数据存储:

User.php

  1 <?php
  2 
  3 namespace App;
  4 
  5 use App\Models\Question;
  6 use Illuminate\Contracts\Auth\MustVerifyEmail;
  7 use Illuminate\Database\Eloquent\SoftDeletes;
  8 use Illuminate\Foundation\Auth\User as Authenticatable;
  9 use Illuminate\Notifications\Notifiable;
 10 
 11 class User extends Authenticatable implements MustVerifyEmail
 12 {
 13     use Notifiable;
 14     #region 支持软删除
 15     use SoftDeletes;
 16     protected $dates = ['deleted_at'];
 17     #endregion
 18     /**
 19      * The attributes that are mass assignable.
 20      *
 21      * @var array
 22      */
 23     protected $fillable = [
 24         'name', 'email', 'password', 'avatar', 'activation_token'
 25     ];
 26 
 27     /**
 28      * The attributes that should be hidden for arrays.
 29      *
 30      * @var array
 31      */
 32     protected $hidden = [
 33         'password', 'remember_token',
 34     ];
 35 
 36     /**
 37      * The attributes that should be cast to native types.
 38      *
 39      * @var array
 40      */
 41     protected $casts = [
 42         'email_verified_at' => 'datetime',
 43     ];
 44 
 45 
 46     /**添加用户模型和问题模型的模型关联
 47      * @return \Illuminate\Database\Eloquent\Relations\HasMany
 48      */
 49     public function questions()
 50     {
 51         return $this->hasMany(Question::class);
 52     }
 53 
 54 
 55     /** 添加用户模型和回答模型的模型关联 一个用户可以有多个回答
 56      * @return \Illuminate\Database\Eloquent\Relations\HasMany
 57      */
 58     public function answers()
 59     {
 60         return $this->hasMany(Answer::class);
 61     }
 62 
 63 
 64     public function followQuestions()
 65     {
 66         //默认表名 可以不设置后面三个参数,自定义表名需要设置
 67         return $this->belongsToMany(Question::class, 'users_questions', 'question_id', 'user_id')->withTimestamps();
 68     }
 69 }
 70 
 71 
User.php

Question.php

  1 <?php
  2 
  3 namespace App\Models;
  4 
  5 use App\Answer;
  6 use App\Topic;
  7 use App\User;
  8 use Illuminate\Database\Eloquent\Model;
  9 use Illuminate\Database\Eloquent\SoftDeletes;
 10 
 11 class Question extends Model
 12 {
 13     //软删除 添加
 14     use SoftDeletes;
 15     //
 16     protected $fillable = ['title', 'content', 'user_id'];
 17     //支持软删除 添加
 18     protected $dates = ['deleted_at'];
 19 
 20     public function topics()
 21     {
 22         return $this->belongsToMany(
 23             Topic::class,
 24             'questions_topics' //表名我设置的是questions_topics,可能不是系统自动解析的question_topic
 25         )->withTimestamps();//withTimestamps操作questions_topics表中create_at及updated_at字段的
 26     }
 27 
 28     public function user()
 29     {
 30         return $this->belongsTo(User::class);
 31     }
 32 
 33     /** scope+请求名命名的
 34      * @return bool
 35      */
 36     public function scopePublished($query)
 37     {
 38         return $query->where('is_hidden', 'F');//等于F表示不隐藏
 39     }
 40 
 41 
 42     /** 一个问题有多个回答
 43      * @return \Illuminate\Database\Eloquent\Relations\HasMany
 44      */
 45     public function answers()
 46     {
 47         return $this->hasMany(Answer::class);
 48     }
 49 
 50 
 51     public function followUsers()
 52     {
 53         //默认表名 可以不设置后面三个参数,自定义表名需要设置
 54         return $this->belongsToMany(Question::class, 'users_questions', 'user_id', 'question_id')->withTimestamps();
 55     }
 56 
 57 }
 58 
 59 
Question.php
posted @ 2020-03-01 00:46  dzkjz  阅读(269)  评论(0编辑  收藏  举报