zoukankan      html  css  js  c++  java
  • Laravel Vuejs 实战:开发知乎 (18-19)用户关注问题

    1.添加授权策略

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

    提示:使用policy

      1 php artisan make:policy QuestionPolicy

    QuestionPolicy文件:

      1 <?php
      2 
      3 namespace AppPolicies;
      4 
      5 use AppModelsQuestion;
      6 use AppUser;
      7 use IlluminateAuthAccessHandlesAuthorization;
      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=" 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 IlluminateDatabaseMigrationsMigration;
      4 use IlluminateDatabaseSchemaBlueprint;
      5 use IlluminateSupportFacadesSchema;
      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 AppModels;
      4 
      5 use AppAnswer;
      6 use AppTopic;
      7 use AppUser;
      8 use IlluminateDatabaseEloquentModel;
      9 use IlluminateDatabaseEloquentSoftDeletes;
     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 IlluminateDatabaseEloquentRelationsHasMany
     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 AppModelsQuestion;
      6 use IlluminateContractsAuthMustVerifyEmail;
      7 use IlluminateDatabaseEloquentSoftDeletes;
      8 use IlluminateFoundationAuthUser as Authenticatable;
      9 use IlluminateNotificationsNotifiable;
     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 IlluminateDatabaseEloquentRelationsHasMany
     48      */
     49     public function questions()
     50     {
     51         return $this->hasMany(Question::class);
     52     }
     53 
     54 
     55     /** 添加用户模型和回答模型的模型关联 一个用户可以有多个回答
     56      * @return IlluminateDatabaseEloquentRelationsHasMany
     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 AppHttpControllers;
      4 
      5 use AppHttpRequestsQuestionStoreRequest;
      6 use AppModelsQuestion;
      7 use AppRepositoriesQuestionRepository;
      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 IlluminateContractsViewFactory|IlluminateViewView
     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 IlluminateContractsViewFactory|IlluminateViewView
     48      */
     49     public function create()
     50     {
     51         //
     52         return view('questions.create');
     53     }
     54 
     55 
     56     /**
     57      * @param QuestionStoreRequest $request
     58      * @return IlluminateHttpRedirectResponse
     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 IlluminateContractsViewFactory|IlluminateViewView
     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 IlluminateContractsViewFactory|IlluminateHttpRedirectResponse|IlluminateViewView
    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 IlluminateHttpRedirectResponse
    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 IlluminateHttpRedirectResponse
    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 AppHttpControllers;
      4 
      5 use AppHttpRequestsQuestionStoreRequest;
      6 use AppModelsQuestion;
      7 use AppRepositoriesQuestionRepository;
      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 IlluminateContractsViewFactory|IlluminateViewView
     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 IlluminateContractsViewFactory|IlluminateViewView
     48      */
     49     public function create()
     50     {
     51         //
     52         return view('questions.create');
     53     }
     54 
     55 
     56     /**
     57      * @param QuestionStoreRequest $request
     58      * @return IlluminateHttpRedirectResponse
     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 IlluminateContractsViewFactory|IlluminateViewView
     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 IlluminateContractsViewFactory|IlluminateHttpRedirectResponse|IlluminateViewView
    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 IlluminateHttpRedirectResponse
    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 IlluminateHttpRedirectResponse
    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 AppModelsQuestion;
      6 use IlluminateContractsAuthMustVerifyEmail;
      7 use IlluminateDatabaseEloquentSoftDeletes;
      8 use IlluminateFoundationAuthUser as Authenticatable;
      9 use IlluminateNotificationsNotifiable;
     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 IlluminateDatabaseEloquentRelationsHasMany
     48      */
     49     public function questions()
     50     {
     51         return $this->hasMany(Question::class);
     52     }
     53 
     54 
     55     /** 添加用户模型和回答模型的模型关联 一个用户可以有多个回答
     56      * @return IlluminateDatabaseEloquentRelationsHasMany
     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 AppModels;
      4 
      5 use AppAnswer;
      6 use AppTopic;
      7 use AppUser;
      8 use IlluminateDatabaseEloquentModel;
      9 use IlluminateDatabaseEloquentSoftDeletes;
     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 IlluminateDatabaseEloquentRelationsHasMany
     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
  • 相关阅读:
    C# dynamic使用
    Linq简介二
    遇事处理方式
    为什么select关键字没有放到前面而是放到了后面
    decimal、float、double区别
    ViewBag、ViewData、TempData区别
    CommandBehavior.CloseConnection的使用
    LINQ简介一
    ViewBag、ViewData使用
    SQL Server 使用WriteText 存储大容量数据
  • 原文地址:https://www.cnblogs.com/dzkjz/p/12387576.html
Copyright ? 2011-2022 开发猿


http://www.vxiaotou.com