ReactとLaravelで投稿機能を作成してみた(バックエンド編)

スポンサーリンク

まずはじめに完成イメージです。

画面上部に投稿用のテキストエリアが存在します。

テキストエリアの下には投稿のレコードが縦に並びます。

レコード内には、ユーザ画像、ユーザ名、日付、本文、高評価アイコン、低評価アイコン、削除アイコンが表示されます。

高評価ボタンもしくは低評価アイコンを押下するとそれぞれの右側にある数字がカウントアップする仕組みとなっています。

削除アイコンをクリックすると投稿を削除できます。

※ソースコードはとても冗長的だと思います(笑)

それどもいいよって優しい方は見ていってください!

ご指摘は大歓迎です!

バックエンド実装(コントローラ)

まずは投稿情報を返すAPI

    /**
     * 投稿データを返す
     *
     * @return \Illuminate\Http\Response
     */
    public function index(Request $request)
    {
        
        $user = \Auth::user();
        $micropost = new Micropost;
        
        if($request->input('since_id') != 0) {
            $microposts = $micropost->makeList($user->id)
                ->where('microposts.id', '<', $request->input('since_id'))
                ->orderBy('id', 'DESC')
                ->limit(15)
                ->get();
        } else if($request->input('max_id') != 0){
            $microposts = $micropost->makeList($user->id)
                ->where('microposts.id', '>', $request->input('max_id'))
                ->orderBy('id', 'DESC')
                ->limit(15)
                ->get();
        } else {
            $microposts = $micropost->makeList($user->id)
                ->orderBy('id', 'DESC')
                ->limit(15)
                ->get();            
        }
        
        return response()->json($microposts);
    }

次に高評価を返すAPI

    //高評価カウンタの更新を行う。
    function updateHighEvauate(Request $request) 
    {
        $user = \Auth::user();
        
        $micropostHighEvaluate = new MicropostHighEvaluate;
        $micropostLowEvaluate = new MicropostLowEvaluate;
        $highEvaluateSelectFlag = $micropostHighEvaluate->checkExistHighEvaluate($user->id,$request->input('post_id'));
        $lowEvaluateSelectFlag = $micropostLowEvaluate->checkExistLowEvaluate($user->id,$request->input('post_id'));
        
        if ($highEvaluateSelectFlag) {
            //すでにユーザが高評価をつけていたらレコードを削除する
            MicropostHighEvaluate::where("micropost_id",$request->input('post_id'))
                ->where("user_id",$user->id)
                ->delete();
            $highEvaluateSelectFlag = false;
        } else {
            //低評価が付いていれば、低評価テーブルのレコード削除
            if ($lowEvaluateSelectFlag) {
                MicropostLowEvaluate::where("micropost_id",$request->input('post_id'))
                    ->where("user_id",$user->id)
                    ->delete();
                $lowEvaluateSelectFlag = false;
            }
            //高評価レコードを生成
            MicropostHighEvaluate::create([
                'micropost_id' => $request->input('post_id'),
                'user_id' => $user->id,
            ]);
            $highEvaluateSelectFlag = true;
        }
        $micropost = Micropost::find($request->input('post_id'));
        
        $data = [
            'id' => $micropost->id,
            'highEvaluates' => $micropost->micropostHighEvaluates()->count(),
            'lowEvaluates' => $micropost->micropostLowEvaluates()->count(),
            'highEvaluateSelected' => $highEvaluateSelectFlag = $highEvaluateSelectFlag == 0 ? null : 1,
            'lowEvaluateSelected' => $lowEvaluateSelectFlag = $lowEvaluateSelectFlag == 0 ? null : 1
        ];

        return json_encode($data);

    }

そして低評価を返すAPI

    //低評価カウンタの更新を行う。
    function updateLowEvauate(Request $request) 
    {
        $user = \Auth::user();
        
        $micropostHighEvaluate = new MicropostHighEvaluate;
        $micropostLowEvaluate = new MicropostLowEvaluate;
        $highEvaluateSelectFlag = $micropostHighEvaluate->checkExistHighEvaluate($user->id,$request->input('post_id'));
        $lowEvaluateSelectFlag = $micropostLowEvaluate->checkExistLowEvaluate($user->id,$request->input('post_id'));
        
        if ($lowEvaluateSelectFlag) {
            MicropostLowEvaluate::where("micropost_id",$request->input('post_id'))
                ->where("user_id",$user->id)
                ->delete();
            $lowEvaluateSelectFlag = false;
        } else {
            if ($highEvaluateSelectFlag) {
                MicropostHighEvaluate::where("micropost_id",$request->input('post_id'))
                    ->where("user_id",$user->id)
                    ->delete();
                $highEvaluateSelectFlag = false;
            }
            MicropostLowEvaluate::create([
                'micropost_id' => $request->input('post_id'),
                'user_id' => $user->id,
            ]);
            $lowEvaluateSelectFlag = true;
        }
        $micropost = Micropost::find($request->input('post_id'));
        $data = [
            'id' => $micropost->id,
            'highEvaluates' => $micropost->micropostHighEvaluates()->count(),
            'lowEvaluates' => $micropost->micropostLowEvaluates()->count(),
            'highEvaluateSelected' => $highEvaluateSelectFlag = $highEvaluateSelectFlag == 0 ? null : 1,
            'lowEvaluateSelected' => $lowEvaluateSelectFlag = $lowEvaluateSelectFlag == 0 ? null : 1
        ];

        return json_encode($data);
    }

投稿削除API

    /**
     * 投稿を削除する
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function destroy($id)
    {
        $user = \Auth::user();
        $micropost = Micropost::find($id);
        
        if ($user->id === $micropost->user_id) {
            $micropost->delete();
            return response()->json(['result' => 'success'],200);
        }
        
        return response()->json(['result' => 'Bad request'],400);
    }

投稿保存API

    /** 
     * 投稿保存
     *
     * @param  Http\Requests\MicropostsRequest $request
     * @return \Illuminate\Http\Response
     */
    public function store(MicropostsRequest $request)
    {
        $user = \Auth::user();
        
         $micropost = new Micropost;
        
        $user->microposts()->create([
            'content' => $request->content,
        ]);
        

            $microposts = $micropost->makeList($user->id)
            ->where('microposts.id', '>', $request->input('max_id'))
            ->orderBy('id', 'DESC')
            ->get();
        
        return response()->json($microposts,200);
    }

バックエンド実装(モデル)

投稿モデル

    public function makeList($userId) {
        $microposts = $this->makeMicropostList($userId);
        return $microposts; 
    }

    public function makeMicropostList($userId) {
        $sub_query_h_evaluate = Micropost::select('microposts.id', DB::raw('count(mhe.micropost_id) as high_evaluate_counts'))
                ->join('micropost_high_evaluates as mhe', 'microposts.id', '=', 'mhe.micropost_id')
                ->groupBy('microposts.id');
                
        $sub_query_l_evaluate = Micropost::select('microposts.id', DB::raw('count(mle.micropost_id) as low_evaluate_counts'))
                ->join('micropost_low_evaluates as mle', 'microposts.id', '=', 'mle.micropost_id')
                ->groupBy('microposts.id');
                
        $sub_query_h_evaluate_c = Micropost::select('microposts.id', DB::raw('count(mhe.micropost_id) as high_evaluate_user_selected'))
                ->join('micropost_high_evaluates as mhe', 'microposts.id', '=', 'mhe.micropost_id')
                ->where('mhe.user_id', $userId)
                ->groupBy('microposts.id');
                
        $sub_query_l_evaluate_c = Micropost::select('microposts.id', DB::raw('count(mle.micropost_id) as low_evaluate_user_selected'))
                ->join('micropost_low_evaluates as mle', 'microposts.id', '=', 'mle.micropost_id')
                ->where('mle.user_id', $userId)
                ->groupBy('microposts.id');
        
        $micropostList = Micropost::select(
            'microposts.id', 
            'microposts.user_id',
            'microposts.content',
            'microposts.latitude',
            'microposts.longitude',
            'microposts.altitude',
            'microposts.created_at', 
            'users.name',
            'high_evaluates.high_evaluate_counts', 
            'low_evaluate.low_evaluate_counts',
            'high_evaluate_user.high_evaluate_user_selected', 
            'low_evaluate_user.low_evaluate_user_selected'
        )

        ->leftJoin(DB::raw("({$sub_query_h_evaluate->toSql()}) as high_evaluates"),'microposts.id', '=', 'high_evaluates.id')
        ->mergeBindings($sub_query_h_evaluate->getQuery())
        ->leftJoin(DB::raw("({$sub_query_l_evaluate->toSql()}) as low_evaluate"),'microposts.id', '=', 'low_evaluate.id')
        ->mergeBindings($sub_query_l_evaluate->getQuery())
        ->leftJoin(DB::raw("({$sub_query_h_evaluate_c->toSql()}) as high_evaluate_user"),'microposts.id', '=', 'high_evaluate_user.id')
        ->mergeBindings($sub_query_h_evaluate_c->getQuery())
        ->leftJoin(DB::raw("({$sub_query_l_evaluate_c->toSql()}) as low_evaluate_user"),'microposts.id', '=', 'low_evaluate_user.id')
        ->mergeBindings($sub_query_l_evaluate_c->getQuery())
        ->leftjoin('users', 'microposts.user_id', '=', 'users.id');
        
        return $micropostList; 
    }

高評価モデル

class MicropostHighEvaluate extends Model
{
    protected $fillable = [
        'micropost_id', 'user_id',
    ];
    
    public function checkExistHighEvaluate($userId,$micropostId)
    {
        return $this->where('user_id', $userId)->where('micropost_id', $micropostId)->exists();
    }
}

低評価モデル

class MicropostLowEvaluate extends Model
{
    protected $fillable = [
        'micropost_id', 'user_id',
    ];
    
    public function checkExistLowEvaluate($userId,$micropostId)
    {
        return $this->where('user_id', $userId)->where('micropost_id', $micropostId)->exists();
    }
}

細かいところは載せていないですが、うまい具合に組み合わせていただければバックエンドは実装できると思います。

次回はフロントエンドやっていきます。

Laravel 未分類
スポンサーリンク
エンジニアの日記

コメント