• Laravel 5.8 做个知乎 7 ——话题 多对多的保存(collect方法 with方法 attach方法等) 传统模式与Repository(仓库)模式的简单应用


    1 传统模式

    1.1 模板代码

    esourcesviewsquestionscreate.blade.php

    <select  class="js-example-basic-multiple js-example-data-ajax form-control" name="topics[]" multiple="multiple">
    
    </select>

    1.2 控制器代码

    appHttpControllersQuestionsController.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();
        }
    View Code

    1.3 模型

    appQuestion.php

    <?php
    
    namespace App;
    
    use IlluminateDatabaseEloquentModel;
    
    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();
        }
    }
    View Code

    appTopic.php

    <?php
    
    namespace App;
    
    use IlluminateDatabaseEloquentModel;
    
    class Topic extends Model
    {
        //
        protected $fillable = ['name','questions_count'];
        
        public function questions()
        {
            return $this->belongsToMany(Question::class)
              ->withTimestamps();
        }
        
    }
    View Code

    1.4 保存后显示

    appHttpControllersQuestionsController.php

        public function show($id)
        {
            //
            //$question = Question::find($id);
            $question = Question::where('id',$id)->with('topics')->first();
            return view('questions.show',compact('question'));
        }

    esourcesviewsquestionsshow.blade.php

     @foreach($question->topics as $topic)
           <span class="topic">{{$topic->name}}</span>
     @endforeach

    2 Repository模式

    2.1 显示页面的重构

    新建 appRepositoriesQuestionRepository.php

    <?php
    namespace AppRepositories;
    use AppQuestion;
    
    class QuestionRepository  
    {
        /**
         * 根据question的id查找topic 列表
         * @param $id
         */
        public function byIdWithTopics($id)
        {
            $question = Question::where('id',$id)->with('topics')->first();
            return $question;
        }
    }

    appHttpControllersQuestionsController.php

    use AppRepositoriesQuestionRepository;
        /**
         * 依赖注入
         * QuestionsController constructor.
         * @param AppRepositoriesQuestionRepository $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

  • 相关阅读:
    android四大组件之contentprovider
    android自定义控件及自定义组合控件
    android四大组件之activity
    监听鼠标滚动事件,如滚动鼠标出现返回顶部按钮
    滚动鼠标出现某一元素
    checked 选择框选中
    原生JS一些操作
    闭合浮动的方法css
    合理提升WEB前端性能
    JS数组操作
  • 原文地址:https://www.cnblogs.com/polax/p/14948047.html
Copyright © 2020-2023  润新知