未経験がLaravelでポートフォリオを作成

##はじめに
未経験からエンジニア転職を実現する為、Laravelを使用し
ポートフォリオを作成しましたので復習も含め簡単に紹介をさせていただきます。
間違っている部分が多々あるかと思いますが、温かい目でお願いします😭

##アプリ概要
備品管理ができるwebアプリケーション「equipsy」

- 備品の登録・編集・削除
- 備品情報一覧
- 備品名を入力し検索(部分検索)
 


[![Image from Gyazo](https://i.gyazo.com/77c4e3149dd3a64d162fc920a550af6c.png)](https://gyazo.com/77c4e3149dd3a64d162fc920a550af6c)

##機能一覧

- ユーザー登録・ログイン・ログアウト
- CRUD
- レスポンシブデザイン
- 部分検索
- ページネーション 

##使用技術

###フロントエンド
- Bootstrap
- HTML
- CSS

###バックエンド
- PHP 8.0.10
- Laravel 8.61.0

###その他
- PHPMyAdmin
- Laravel sail
- VSCode
- GitHub
- AWS

##復習　①環境構築
Laravel sailで環境構築

Dockerをインストール後、既存アプリケーションへの
sailインストール

```
%　composer require laravel/sail --dev
%　php artisan sail:install
```

最後にsailを立ち上げ。
＊Bashエイリアスを設定するとsailコマンドより
　簡単に実行できるようになる。

```
./vendor/bin/sail up
```
自分の場合、Dockerのバージョンが最新でなかったために
エラーが発生し少し時間を要してしまった。

##②登録機能
Postコントローラーを呼び出す処理を書いたが、エラーが発生し調査すると
Laravel8の変更点の一つでデフォルトの名前空間を削除したというのが関係しているみたいだった。解決策は複数あったが今回は、完全な名前空間を使用することで解決。

個別のパスに、->middleware('auth')を書く事で認証済みのユーザーのみが入れるように設定。ログイン画面へリダイレクトする。

エラー発生時

```web.php
Route::get('/create', [PostController::class, 'create'])->name('post.create')->middleware('auth');
```

エラー発生後の変更

```web.php
Route::get('/create', [App\Http\Controllers\PostController::class, 'create'])->name('post.create')->middleware('auth');
Route::post('/create', [App\Http\Controllers\PostController::class, 'store'])->name('post.store');
```

Postモデルのメンバ変数、$fillableを使用することで
create()でデータを追加する際に、値を代入を許可するフィールドを設定する。
それ以外は代入が拒否される。

メンバ変数 = クラスの中に定義するそのクラス固有の変数のこと。

```Post.php
class Post extends Model
{
    use HasFactory;

    protected $fillable = [
        'control_number',
        'name',
        'quantity',
        'user_id'
    ];
```

PostController。バリデーションは、item・quantityのみ必須。
インスタンスを作成して登録された値を代入しデータベースに登録された値を保存する。
登録ボタンを押した後、一覧ページへリダイレクトする。

```PostController.php
    public function create()
    {
        //
        return view('create');
    }

    public function store(Request $request)
    {
        //バリデーション
        $validator = Validator::make($request->all(),[
            'item' => 'required',
            'quantity' => 'required',
        ]);
        //バリデーションエラー
        if($validator->fails()) {
            return redirect()->back()
            ->withInput()
            ->withErrors($validator);
        }
        //Postモデルのインスタンスを作成
        $post = new Post;
        $post->control_number = $request->input('control_number');
        $post->item = $request->input('item');
        $post->quantity = $request->input('quantity');
        $post->user_id = Auth::id();//ログインしているユーザーidを登録している

        $post->save();

        //登録後に一覧画面へ遷移
        return redirect('/index');

    }

```

##③一覧表示・部分検索

```web.php
Route::get('/index', [App\Http\Controllers\PostController::class, 'index'])->name('post.index')->middleware('auth');
```

```PostController.php
    public function index(Request $request)
    {

        // 選ばれたユーザーを取得する
        $id=Auth::user()->id;

        $search = $request->input('search') ?: "";
        
        $query = Post::query();

        if(!empty($search))
        {
            $query->where('user_id', $id)
            ->where('item','like','%'.$search.'%');
        }else{
            $query->where('user_id', $id);
        }

        $posts = $query->paginate(12);

        return view('index', compact('posts'));
    }
```

$query = Post::query();← SQL文(Postsテーブル)をデータベースに発行。
if文を使用し、検索が空でない場合は現在認証中ユーザーと紐づいているPostsテーブルのitemカラム(備品名)のデータを部分一致した登録情報を一覧表示する。

空の場合は現在認証中ユーザーと紐づいている登録情報を一覧表示する。

compact()を使用しコントローラーからビューへ値を渡している。

##④編集機能

```web.php
Route::get('/edit/{id}', [App\Http\Controllers\PostController::class, 'edit'])->name('post.edit')->middleware('auth');
```

```PostController.php
    public function edit($id)
    {
        //
        $post = Post::find($id);
        return view('edit', compact('post'));
    }

   public function update(Request $request, $id)
    {
        
        //バリデーション
        $validator = Validator::make($request->all(),[
            'item' => 'required',
            'quantity' => 'required',
        ]);
        //バリデーションエラー
        if($validator->fails()) {
            return redirect()->back()
            ->withInput()
            ->withErrors($validator);
        }        
        $post = Post::find($id);
        $post->control_number = $request->input('control_number');
        $post->item = $request->input('item');
        $post->quantity = $request->input('quantity');
        $post->user_id = Auth::id();//ログインしているユーザーidを登録している

        $post->save();

        //登録後に一覧画面へ遷移
        return redirect('/index');
    }
```

**edit**
どの編集をするか、```$post = Post::find($id);``` として代入している。
compact()でコントローラーからビューに値を渡している。

**update**
storeとほぼ同じ記述だが、```$post = Post::find($id);```で
idからとってきた情報を代入している。



##⑤削除機能

```web.php
Route::post('/destroy/{id}', [App\Http\Controllers\PostController::class, 'destroy'])->name('post.destroy');
```

```PostController.php
    public function destroy($id)
    {
        //
        $post = Post::find($id);
        $post->delete();

        return redirect('/index');
    }
}
```

どの情報を削除するか```$post = Post::find($id);``` として代入している。

##感想
Qiita初投稿してみて、実際に書きながら整理することで深い理解に繋がることができ
マークアップにも慣れて良い時間だった。これからもっとアウトプットしていこう!!