1 传统模式
1.1 模板代码
\resources\views\questions\create.blade.php
<select class="js-example-basic-multiple js-example-data-ajax form-control" name="topics[]" multiple="multiple"> </select>
1.2 控制器代码
\app\Http\Controllers\QuestionsController.php
public function store(StoreQuestionRequest $request) { //自动过滤掉token值 //$this->validate($request,$rules,$message); $topics = $this->normailizeTopic($request->get('topics')); $data = $request->all(); $save = [ 'title' =>$data['title'], 'body' =>$data['body'], 'user_id' =>Auth::id() ]; $rs = Question::create($save); $rs->topics()->attach($topics); return redirect()->route('question.show',[$rs->id]); }
private function normailizeTopic(array $topics) { //collect 遍历方法 return collect($topics)->map(function ($topic){ if(is_numeric($topic)){ Topic::find($topic)->increment('questions_count'); return (int)$topic; } $newTopic = Topic::create(['name'=>$topic,'questions_count'=>1]); return $newTopic->id; })->toArray(); }
1.3 模型
\app\Question.php
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Question extends Model { //fillable为白名单,表示该字段可被批量赋值;guarded为黑名单,表示该字段不可被批量赋值。 protected $fillable = ['title','body','user_id']; public function isHidden() { return $this->is_hidden === 'T'; } public function topics() { //多对多的关系 //belongsToMany如果第二个参数不是question_topic的话 可以通过第二个参数传递自定义表名 return $this->belongsToMany(Topic::class,'question_topic') ->withTimestamps(); } }
\app\Topic.php
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Topic extends Model { // protected $fillable = ['name','questions_count']; public function questions() { return $this->belongsToMany(Question::class) ->withTimestamps(); } }
1.4 保存后显示
\app\Http\Controllers\QuestionsController.php
public function show($id) { // //$question = Question::find($id); $question = Question::where('id',$id)->with('topics')->first(); return view('questions.show',compact('question')); }
\resources\views\questions\show.blade.php
@foreach($question->topics as $topic) <span class="topic">{{$topic->name}}</span> @endforeach
2 Repository模式
2.1 显示页面的重构
新建 \app\Repositories\QuestionRepository.php
<?php namespace App\Repositories; use App\Question; class QuestionRepository { /** * 根据question的id查找topic 列表 * @param $id */ public function byIdWithTopics($id) { $question = Question::where('id',$id)->with('topics')->first(); return $question; } }
\app\Http\Controllers\QuestionsController.php
use App\Repositories\QuestionRepository;
/** * 依赖注入 * QuestionsController constructor. * @param \App\Repositories\QuestionRepository $questionRepository */ public function __construct(QuestionRepository $questionRepository) { $this->middleware('auth')->except(['index','show']); $this->questionRepository = $questionRepository; }
public function show($id) { //$question = Question::where('id',$id)->with('topics')->first(); $question = $this->questionRepository->byIdWithTopics($id); return view('questions.show',compact('question')); }
2.2 代码地址
https://github.com/guainttt/laravel-zhihu/releases/tag/v7.1