7
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

【Laravel】laravelでユーザー管理(ログイン、新規登録)、ファイルのアップロード機能の実装

Posted at

作成にあたって、参考にしたサイト
laravle学習帳

要件定義

ユーザー管理機能(新規登録、ログイン)を実装。

ログインしたら
画像投稿、投稿画像一覧の機能が使えるようにする。

その他
・ログインしているユーザーidと投稿画像のidを紐つけて、どのユーザーが投稿したか管理する。

データベース設計

  • プロジェクト名:laravel_fileup
  • 画像投稿のモデル、テーブルはPost、postsとする
     

postsテーブルのカラム設計

  • id
  • tile:画像のタイトル
  • path:画像の保存先のパス
  • user_id:どのユーザーが投稿したかのため

usersテーブルのカラム設計

こちらは自動で作成されるので割愛

プロジェクトの作成

$ composer create-project --prefer-dist laravel/laravel='5.8' laravel_fileup

.envファイルの編集

database.sqliteの作成

ログイン機能の実装

make::authを使う

$ php artisan make:auth

ログイン時とログアウト時の遷移先を変更する

参考記事:https://qiita.com/LowSE01/items/ffa256439f665740cc8f

app/Http/controllers/Auth/LoginController.php
<?php

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\AuthenticatesUsers;

+ use Illuminate\Http\Request;

class LoginController extends Controller
{
    /*
    |--------------------------------------------------------------------------
    | Login Controller
    |--------------------------------------------------------------------------
    |
    | This controller handles authenticating users for the application and
    | redirecting them to your home screen. The controller uses a trait
    | to conveniently provide its functionality to your applications.
    |
    */

    use AuthenticatesUsers;

    /**
     * Where to redirect users after login.
     *
     * @var string
     */
+    protected $redirectTo = '/posts/create';

    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('guest')->except('logout');
    }

+    public function logout(Request $request)
+   {
+       $this->guard()->logout();
+       $request->session()->flush();
+       $request->session()->regenerate();

+       return redirect('/login');//ログアウト時の遷移先
+  }

}

fileのアップロード用モデルとマイグレーションを作成

$ php artisan make:model Post -m
Model created successfully.
Created Migration: 2019_12_30_005951_create_posts_table

migrationファイルの修正(タイトルとパスのカラムを作成)

database/migrations/2019_12_30_005951_create_posts_table.php
            $table->bigIncrements('id');
+           $table->unsignedInteger('user_id');
+           $table->string('title');
+           $table->text('path');
            $table->timestamps();
+           $table->foreign('user_id')->references('id')->on('users');

マイグレーションの実行

$ php artisan migrate

Post.php(ポストモデルの修正)

postsテーブルへの書き込み権限を付与
Userモデルとの紐付けを記載

app/Post.php
class Post extends Model
{
+    protected $fillable = ['title','path'];

+    public function user() {
+    return $this->belongTo('App\User');}

Userモデルの修正

Postモデルとの紐付けを記載

app/User.php
+  public function posts() {
+    return $this->hasMany('App\Post');
+    }

ファイルのアップロード等を管理するコントローラーの作成

$ php artisan make:controller PostsController
Controller created successfully.

ファイル操作に関連するroutesを作成

参考記事
https://qiita.com/sympe/items/9297f41d5f7a9d91aa11

routes/web.php
// Route::get('/', function () {return view('welcome');});
Auth::routes();
// Route::get('/home', 'HomeController@index')->name('home');
+ Route::resources('posts','PostsController');

新規投稿〜画像保存までの流れを作成

ファイルアップロード用のフォームを作成

resources/views/posts/create.blade.php
@extends('layouts.app')

@section('content')

<div class="container">
  <form method="post" action="/posts" enctype="multipart/form-data">
	{{ csrf_field() }}
  <div class="form-group">
  <label>投稿する画像のタイトルを入力してください</label>
  <input type="text" name="title" class="form-control col-sm-4" value="{{ old('title')}}">
  </div>

  <div class="form-group">
  <label>投稿する画像を選んでください</label>
	<input type="file" id="file" name="file" class="form-control col-sm-4">
  </div>
  <div class="form-group">
	<button type="submit" class="btn btn-primary">アップロード</button>
  </div>
	</form>

  @if ($errors->has('title'))
  <div class="alert alert-danger" role="alert">{{$errors->first('title')}}</div>
  @endif


  @if ($errors->has('file'))
  <div class="alert alert-danger" role="alert">{{$errors->first('file')}}</div>
  @endif


  @if (session('flash_message'))
  <div class="alert alert-success" role="alert">{{ session('flash_message')}}</div>
  @endif

</div>


@endsection

コントローラーの設定

app
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use App\Post;
use App\User;
use App\Http\Requests\CreatePostRequest;
use Carbon\Carbon;

class PostsController extends Controller
{
    //ログインしていないと、PostsController内の処理ができないようにする。
    public function __construct() {
      $this->middleware('auth');
    }

    public function index() {
      $posts = Post::all();
      return view('posts.index')->with('posts',$posts);
    }

    public function create() {
      return view('posts.create');
    }

    public function store(CreatePostRequest $request) {
            $nowtime = Carbon::now();
      //ログインしているユーザーを取得
      $user = Auth::user();
      //ファイル名取得
      $filename = $user->id . "_".$nowtime."_". $request->file('file')->getClientOriginalName();
      //storage/app/publicにファイルを保存する
      $request->file('file')->storeAs('public',$filename);

      $post = new Post();
      $post->title = $request->title;
      $post->path = '/storage/'.$filename;
      $user->posts()->save($post);
      session()->flash('flash_message', '投稿が完了しました');
      return redirect('posts/create');
    }
}

バリデーションの設定をする。

バリデーション用のファイルを作成する。

$ php artisan make:request CreatePostRequest
Request created successfully.

CreatePostRequestを編集する。

app/Http/Request/CreatePostRequest.php
    public function rules()
    {
        return [
+         'title' => 'required',
+         'file' => 'required|image',
        ];
    }

+    public function messages() {
+    return [
+       'title.required' => 'タイトルが入力されていません',
+        'file.required' => '画像を選択してください',
+        'file.image' => '画像ファイルを選択してください',
+    ];

コントローラーに適用する

作成したCreatePostRequestを読み込む
store()メソッドの引数に入れる。

app/Http/controllers/PostsController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use App\Post;
use App\User;
+ use App\Http\Requests\CreatePostRequest;
use Carbon\Carbon;




+ public function store(CreatePostRequest $request) {

シンボリックリンクの作成

$ php artisan storage:link
The [public/storage] directory has been linked.

取得した画像をの一覧表示を実装する。

・やりたいこと画像のタイトルと画像の表示

resources/views/posts/index.blade.php
@extends('layouts.app')

@section('content')

<div class="container">
  <div class="row">
    @foreach($posts as $post)
    <div class="col-md-3" style="margin-top:10px;">
      <img src="{{$post->path}}" width="95%">
    <h3 style="margin-top:3px;text-align:center;">タイトル{{ $post->title}}</h3>
  </div>
    @endforeach
</div>

@endsection

編集モードにて削除コマンドをつける

editメソッドの作成

index.blade.phpに編集モードへのリンクを作成

resources/views/posts/index.blade.php
    @foreach($posts as $post)
    <div class="col-md-3" style="margin-top:10px;">
+      <a href="{{ action('PostsController@edit',$post) }}"><img src="{{$post->path}}" width="95%"></a>
    <h3 style="margin-top:3px;text-align:center;">{{ $post->title}}</h3>
  </div>
    @endforeach

PostsControlerのeditメソッドを作成

app/Http/Controllers/PostsController.php
    public function edit(Post $post) {
      return view('posts.edit')->with('post',$post);
    }

編集ビューの作成
編集ビューに削除ボタン作成

resources/views/posts/edit.blade.php
@extends('layouts.app')

@section('content')

<div class="container">
  <div>
  <img src="{{$post->path}}" width="80%">
  </div>


  <form action="{{ action('PostsController@destroy',$post)}}" method="post">
  {{csrf_field()}}
  {{method_field('delete')}}
      <div class="row" style="margin-top:30px;">
    <button type="submit" class="btn btn-danger col-sm-3">削除する</button>
    </div>
  </form>

</div>

@endsection

PostsControllerにdestroyメソッド(削除メソッド)作成

app/Http/controllers/PostsCotnroller.php
public function destroy(Post $post) {
      $post->delete();
      session()->flash('flash_message', '投稿画像を削除しました');
      return redirect('/');
    }

auth関連で作成したビューを日本語化する

参考記事
https://qiita.com/miya-krow/items/05170462b2f092c95dfa

config/appを変更する

config/app.php
'locale' => 'ja',
'fallback_locale' => 'ja',

en:Engilish
ja:Japanese

ja.jsonファイルを作成して対応する

$ vi resources/lang/ja.json
resources/lang/ja.json
{  "Login"    :"ログイン",
   "Register" :"新規登録",
   "Password" : "パスワード",
   "E-Mail Address": "メールアドレス",
   "Logout":"ログアウト",
   "Name": "ニックネーム",
   "Confirm Password": "パスワード(もう一度入力)"
}

その他

パスワードリセット機能は実装しないので、使えないようにする。

対象部をコメントアウトする

resources/views/auth/login.blade.php
                        <!-- <div class="form-group row">
                            <div class="col-md-6 offset-md-4">
                                <div class="form-check">
                                    <input class="form-check-input" type="checkbox" name="remember" id="remember" {{ old('remember') ? 'checked' : '' }}>

                                    <label class="form-check-label" for="remember">
                                        {{ __('Remember Me') }}
                                    </label>
                                </div>
                            </div>
                        </div> -->

                        <div class="form-group row mb-0">
                            <div class="col-md-8 offset-md-4">
                                <button type="submit" class="btn btn-primary">
                                    {{ __('Login') }}
                                </button>

                                <!-- @if (Route::has('password.request'))
                                    <a class="btn btn-link" href="{{ route('password.request') }}">
                                        {{ __('Forgot Your Password?') }}
                                    </a>
                                @endif -->
                            </div>

urlに直接入力してら、indexに飛ばすようにする。

routes/web.php
Route::get('/', 'PostsController@index');
Auth::routes();
+ Route::get('/password/email', function() {return redirect('/');});
+ Route::get('/password/reset', function() {return redirect('/');});
// Route::get('/home', 'HomeController@index')->name('home');
Route::resource('posts','PostsController');

以上です。

7
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?