Controllerを作成
ResourceController
Controllerファイルを生成する際--resource
と付けることでResourceに対応したControllerを自動的に生成。
HTTP動詞 | URL | アクション | 役割 |
---|---|---|---|
GET | /tweets | index | 一覧表示 |
GET | /tweets/create | create | 新規ツイート入力画面 |
POST | /tweets | store | 新規ツイート投稿処理 |
GET | /tweets/{tweet}/show | show | ツイート詳細画面 |
GET | /tweets/{tweet}/edit | edit | ツイート編集画面 |
PUT/PATCH | /tweets/{tweet} | update | ツイート編集処理 |
DELETE | /tweets/{tweet} | destory | ツイート削除処理 |
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class TweetsConroller extends Controller
{
// 一覧表示
public function index()
{
//
}
// 新規ツイート入力画面
public function create()
{
//
}
// 新規ツイート投稿処理
public function store(Request $request)
{
//
}
// ツイート詳細画面
public function show($id)
{
//
}
// ツイート編集画面
public function edit($id)
{
//
}
// ツイート編集処理
public function update(Request $request, $id)
{
//
}
// ツイート削除処理
public function destroy($id)
{
//
}
}
UsersController
php artisan make:controller UsersController --resource
Routing
<?php
/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/
Route::get('/', function () {
return view('welcome');
});
Auth::routes();
Route::get('/home', 'HomeController@index')->name('home');
// ログイン状態
Route::group(['middleware' => 'auth'], function() {
// ユーザ関連
Route::resource('users', 'UsersController');
});
このクロージャーの中にルートを設定することでログインした時にしかアクセス出来ないようにする。
Route::group(['middleware' => 'auth'], function() {
//
});
Route::resource('users', 'UsersController');
ユーザ機能では一覧
/詳細
/編集
/更新
のみを使用するので第3引数にonly
と記述して使うアクションのみを設定。
Route::resource('users', 'UsersController', ['only' => ['index', 'show', 'edit', 'update']]);
ユーザを取得
ユーザ一覧表示画面
Controller
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
use App\Models\User;
use App\Models\Tweet;
use App\Models\Follower;
class UsersController extends Controller
{
public function index(User $user)
{
$all_users = $user->getAllUsers(auth()->user()->id);
return view('users.index', [
'all_users' => $all_users
]);
}
}
メソッドインジェクション
LaravelにはDI(依存性の注入)というのが内蔵されており、メソッドの引数にインジェクトしたいオブジェクトを書くだけで、そのインスタンスが使用できる。
public function index(User $user)
{
$all_users = $user->getAllUsers(auth()->user()->id);
}
Model
public function getAllUsers(Int $user_id)
{
return $this->Where('id', '<>', $user_id)->paginate(5);
}
View
@extends('layouts.app')
@section('content')
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
@foreach ($all_users as $user)
<div class="card">
<div class="card-haeder p-3 w-100 d-flex">
<img src="{{ $user->profile_image }}" class="rounded-circle" width="50" height="50">
<div class="ml-2 d-flex flex-column">
<p class="mb-0">{{ $user->name }}</p>
<a href="{{ url('users/' .$user->id) }}" class="text-secondary">{{ $user->screen_name }}</a>
</div>
</div>
</div>
@endforeach
</div>
</div>
<div class="my-4 d-flex justify-content-center">
{{ $all_users->links() }}
</div>
</div>
@endsection
フォロー関連の処理
フォロー/フォロー解除/フォローされているか
Controller
フォローとフォロー解除はresourceのどのアクションにも該当しないので、独自に追加。
// フォロー
public function follow(User $user)
{
$follower = auth()->user();
// フォローしているか
$is_following = $follower->isFollowing($user->id);
if(!$is_following) {
// フォローしていなければフォローする
$follower->follow($user->id);
return back();
}
}
// フォロー解除
public function unfollow(User $user)
{
$follower = auth()->user();
// フォローしているか
$is_following = $follower->isFollowing($user->id);
if($is_following) {
// フォローしていればフォローを解除する
$follower->unfollow($user->id);
return back();
}
}
Model
// フォローする
public function follow(Int $user_id)
{
return $this->follows()->attach($user_id);
}
// フォロー解除する
public function unfollow(Int $user_id)
{
return $this->follows()->detach($user_id);
}
// フォローしているか
public function isFollowing(Int $user_id)
{
return (boolean) $this->follows()->where('followed_id', $user_id)->first(['id']);
}
// フォローされているか
public function isFollowed(Int $user_id)
{
return (boolean) $this->followers()->where('following_id', $user_id)->first(['id']);
}
フォローされているかの判定
@if (auth()->user()->isFollowed($user->id))
フォローしているかの判定
@if (auth()->user()->isFollowing($user->id))
Routing
// ログイン状態
Route::group(['middleware' => 'auth'], function() {
// ユーザ関連
Route::resource('users', 'UsersController', ['only' => ['index', 'show', 'edit', 'update']]);
// フォロー/フォロー解除を追加
Route::post('users/{user}/follow', 'UsersController@follow')->name('follow');
Route::delete('users/{user}/unfollow', 'UsersController@unfollow')->name('unfollow');
});
ユーザ詳細画面
- プロフィール
- プロフィールが自身だった時に編集ボタンを追加
- プロフィールが自身以外のユーザだった時にフォロー/フォロー解除/フォローされているかの判定を追加
- 総ツイート数/フォロー数/フォロワー数の表示
- ユーザがツイートしたタイムラインの表示
Controller
public function show(User $user, Tweet $tweet, Follower $follower)
{
$login_user = auth()->user();
$is_following = $login_user->isFollowing($user->id);
$is_followed = $login_user->isFollowed($user->id);
$timelines = $tweet->getUserTimeLine($user->id);
$tweet_count = $tweet->getTweetCount($user->id);
$follow_count = $follower->getFollowCount($user->id);
$follower_count = $follower->getFollowerCount($user->id);
return view('users.show', [
'user' => $user,
'is_following' => $is_following,
'is_followed' => $is_followed,
'timelines' => $timelines,
'tweet_count' => $tweet_count,
'follow_count' => $follow_count,
'follower_count' => $follower_count
]);
}
Model
Tweet
public function getUserTimeLine(Int $user_id)
{
return $this->where('user_id', $user_id)->orderBy('created_at', 'DESC')->paginate(50);
}
public function getTweetCount(Int $user_id)
{
return $this->where('user_id', $user_id)->count();
}
Follower
public function getFollowCount($user_id)
{
return $this->where('following_id', $user_id)->count();
}
public function getFollowerCount($user_id)
{
return $this->where('followed_id', $user_id)->count();
}
ユーザ編集
Controller
$requestで取得したデータをValidator::make
を使ってバリデーションをかける。
Rule::unique('users')->ignore($user->id)
の部分はユニークに設定しているscreen_name
やemail
を自身のIDの時だけ無効にする設定。
public function edit(User $user)
{
return view('users.edit', ['user' => $user]);
}
public function update(Request $request, User $user)
{
$data = $request->all();
$validator = Validator::make($data, [
'screen_name' => ['required', 'string', 'max:50', Rule::unique('users')->ignore($user->id)],
'name' => ['required', 'string', 'max:255'],
'profile_image' => ['file', 'image', 'mimes:jpeg,png,jpg', 'max:2048'],
'email' => ['required', 'string', 'email', 'max:255', Rule::unique('users')->ignore($user->id)]
]);
$validator->validate();
$user->updateProfile($data);
return redirect('users/'.$user->id);
}
Model
$paramsの中に画像があれば処理を分けています。
$file_name = $params['profile_image']->store('public/profile_image/');
とすることで画像ファイルが/storage/app/public/profile_image/
に保存される。
public function updateProfile(Array $params)
{
if (isset($params['profile_image'])) {
$file_name = $params['profile_image']->store('public/profile_image/');
$this::where('id', $this->id)
->update([
'screen_name' => $params['screen_name'],
'name' => $params['name'],
'profile_image' => basename($file_name),
'email' => $params['email'],
]);
} else {
$this::where('id', $this->id)
->update([
'screen_name' => $params['screen_name'],
'name' => $params['name'],
'email' => $params['email'],
]);
}
return;
}