未経験者がLaravel共同開発での詰まりポイントの「メモ」をまとめてみた【Laravel編】

#はじめに
タイトルの通り、共同開発講座を受講中に起きたトラブルや詰まりポイントをまとめたメモ（約50記事）をジャンル別に全て公開します。
ジャンルは以下の通りなので、気になるものがあればぜひご覧ください。
###【ジャンル一覧】
・[GitHub関連](https://qiita.com/kei_Q/items/1e421eef9b3bdbcdd9e9)
・[Laravel関連](https://qiita.com/kei_Q/items/79ef7679b28bb3c9738e)
・[データベース（migration/seeding）関連](https://qiita.com/kei_Q/items/cf13f486628bb5662089)
・[環境関連](https://qiita.com/kei_Q/items/412a9695f26aad25a99c)
・[総まとめ集](https://qiita.com/kei_Q/items/e197268fc29fdd664b64)

下記の点を、ご了承ください。
・ジャンルで統一しているため、内容に関しては統一性はありません。
・メモの難易度もバラバラです。
・初学者向けの内容となっております。
・自分用のメモを転用しておりますので、表現が稚拙な部分があるかと思います。
**・あくまで僕のメモです！！**


#・MVCの考え方（言葉で説明）
**ユーザ登録機能を題材にMVCの実際の動きを確認します**

ルーティング(Web.php)の

```
Route::get('signup', 'Auth\RegisterController@showRegistrationForm')->name('signup');
```

この意味は
signupと検索されればRegisterControllerにいって、showRegistrationFormアクションを発動させる
↓
RegisterControllerに行くとshowRegistrationFormアクションはトレイトで表記されている。

ちなみに
トレイトの内容は

```
 return view(‘auth.register’)
```

となっていて
「Authフォルダにある、register.blade.phpというviewファイルを表示しなさい」という意味
つまり
Authフォルダを作って、その中にregister.blade.phpを作成してそれが呼び出されるようにする


#・LaravelCollective導入時のエラー

###Laravel Collectiveとは
Laravelには便利なライブラリがたくさんある。
Larval collective はその中の一つ
Laravel のビューでフォームを記述するには直接HTMLを記述する方法とヘルパー関数(HTML/Formヘルパー)を使う方法がある。
ヘルパー関数を使う場合はこのパッケージをcomposerでインストールする必要がある。
なお、LaravelCollective/htmlはLaravel4では標準で組み込まれていたが、Laravel5からは別パッケージになった。


###導入時のエラーの詳細

Webコンテナに入る

```
[vagrant@local-docker lara-d]$ docker-compose exec web bash
```

紹介されたコマンド実行
↓
以下のようなエラーが起こる

```
[root@1b08bc3fd4bf html]# composer require "laravelcollective/html":"5.5.*"
./composer.json has been updated
Running composer update laravelcollective/html
Loading composer repositories with package information
Updating dependencies
Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - laravelcollective/html[v5.5, ..., 5.5.x-dev] require illuminate/http 5.5.* -> found illuminate/http[v5.5.0, ..., 5.5.x-dev] but it conflicts with another require.
    - laravelcollective/html v5.5.2 requires illuminate/http 5.6.* -> found illuminate/http[v5.6.0, ..., 5.6.x-dev] but it conflicts with another require.
    - Root composer.json requires laravelcollective/html 5.5.* -> satisfiable by laravelcollective/html[v5.5, ..., 5.5.x-dev].


Installation failed, reverting ./composer.json and ./composer.lock to their original content.
```


###導入時のエラーの原因

####原因①
**PHPのバージョンとLaravelのバージョンが一致していなかったのが原因。**
**適応するバージョンにアップデートしたら無事導入できた。**

####原因②
**インストール実行コマンドの仕様が違っていた。**

紹介されていたコマンド

```
composer require "laravelcollective/html":"5.5.*"
```

調べてインストール成功したコマンド

```
composer require "laravelcollective/html":"^5.5"
```

**※ちなみにLaravelCollectiveはプロジェクト毎にインストールしないといけないので注意**


#・セッションの使用方法

セッションの使用方法は大きく３つある

①Requestインスタンスを用いる方法
②グローバルSessionへルパ関数を利用する方法
（③ファサードを利用する方法）

今回は①のRequestインスタンスを利用する方法で実装する

####セッションへのデータ保存（Requestインスタンス経由）
```
$request -> session () -> put ( ‘ key ’  , ’ value ’ ) ; 
```

ここのkeyは勝手に名前つけて良いの？→良い！
Valueは何を入れたら良いの？→保存したい値！

####セッションデータの取得（Requestインスタンス経由）

```
$request->session () -> get( ‘ key ’ );
```

####データの保存先
Laravelの
strage > framework > sessions  に格納されていく！



#・フォームリクエストの作成方法
コントローラ作成する時みたいに
**php artisan make:request CreateProductRequest**
でリクエストを作成する

作成したファイルにバリデーションを記載していく
この時、authorize()はとりあえずtureにしておく（細かい設定もある）


```php:CreateProductRequest
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;

//クラス名は作成時に指定したものになる
class CreateProductRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
        //細かい設定もあるようだけど、とりあえずtureにしとく
    }
    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
　　//ここにバリデーションを書いていく
    public function rules()
    {
        return [
            'product_name' => 'required|string|max:20',
            'category_id' => 'required|numeric|exists:m_categories,id',
            'price' => 'required|numeric',
            'sale_status_id' => 'required|numeric|exists:m_sales_statuses,id',
            'product_status_id' => 'required|numeric|exists:m_products_statuses,id',
            'description' => 'required|string|max:191',
        ];
    }
}
```

コントローラのupdateアクションで、さっき作成したフォームリクエスト（バリデーション）を用いて、リクエスト情報を更新する。


```php:Controllerのupdateアクション
ここに
public function update(CreateProductRequest $request, $id)
    {
        $product = MProduct::with(['category', 'sale_status', 'product_status'])->find($id);
        // dd($request);
        $product->product_name = $request->product_name;
        $product->category_id = $request->category_id;
        $product->price = $request->price;
        $product->sale_status_id = $request->sale_status_id;
        $product->product_status_id = $request->product_status_id;
        $product->description = $request->description;
        $product->save();
        return redirect('seller/items');
    }
```


**フォームリクエストを使用することで、更新時には、まずCreateProductRequestに記載したバリデーションを実行してくれて、それがtureであれば（ authorize()の話 ）コントローラの内容が実行されるという流れ。
もしバリデーションに引っかかった場合はエラー情報を持たせて、直前のページにリダイレクトしてくれる。**


#・リレーション先のデータを取得する

モデルにリレーションを貼って、リレーション先のデータを取得できるようにします

例えば...

**Product テーブル**
→商品に関するテーブルで登録された商品がたくさん入っている

**Categories テーブル**
→Productテーブルの親テーブルで、商品をカテゴリー別に分類するためのカテゴリーデータが入っている

この二つのテーブルにリレーションを貼ります

####リレーションの貼り方

**Product モデル**

```php
class Product extends Model
{
・・・
public function category()
    {
        return $this->belongsTo(Category::class);
    }
・・・
}
```

category メソッドを作成して
「このクラスはCategoryモデルに属するんだよ」
と記述してあげる。
→Productモデルの親はCategoryモデルであり、Productモデルの中身の一つである’カテゴリー’カラムのデータは、Categoryテーブルから持ってくる。
→ProductモデルはCategoryモデルに属する！！

**Category モデル**

```php
class Category extends Model
{
・・・
    public function Products()
    {
        return $this->hasMany(Product::class);
    }
}
```

Products メソッドを作成して
「このクラスはProductモデルをたくさん保有しているよ」
と記述してあげる。
→Categoryモデルの子はProductモデルであり、Categoryモデルの中身の一つである’カテゴリー’カラムのデータを持つProductモデルはたくさんある。
→CategoryモデルはたくさんのProductモデルを保有する！！


**上記二つのテーブル（モデル）間のリレーションを貼りたい場合は、モデル内に上記のような親子関係を考慮した記述を双方に対して記載してあげることでリレーションを張ることができる。**

コントローラで取得の方法を確認していく↓

**コントローラの記述**

```
public function show($id)//Product $product ?
    {
　　　　　//Productモデルから$idの商品データを取得
        $pd_info = Product::find($id);
　　　　　//上記で定義した商品データからcategory_idを取得できるようになる
        $pd_category = Category::find($pd_info -> category_id);
      
        return view('iteminfo', 
        [
            'pd_info' => $pd_info,
            'pd_category' => $pd_category,
        ]);
    }
```

Productモデルから$idの商品データを取得し、その商品データからcategory_idを取得できるようになる。
つまり、
**Categoryモデルからデータを取得している！**ということ


#・ルーティング prefix の使い方

**Prefixとは**
直訳すると「接頭語」という意味
ルーティングする上での意味はprefixで指定した文字を最初に設置するっという感じの意味合いになる（url のアクセスに関する話）


**使用例**

```php
Route::group(["prefix"=> 'iteminfo'], function() {
    Route::get('/{id}', 'ProductController@show');
    Route::post('/add', 'ProductController@addCart')->name('addcart');
});
```

**解説）**

```php
Route::group(["prefix"=> 'iteminfo']
```

Prefix => ‘iteminfo’  とすることで、urlのアクセス部分を統一することができる。
この場合iteminfoというurlにアクセスされるルーティングを一まとめ（グループ）にすることができる。

上記のグループの中身である

```php
Route::get('/{id}', 'ProductController@show');
Route::post('/add', 'ProductController@addCart')->name('addcart');
```

この部分は iteminfo 以降のurl部分を記述していて、
一つ目は iteminfo/id にアクセスされた場合のルーティングとなる。


#・新規プロジェクトの立ち上げ方法(バルスした時に新しいプロジェクトを立ち上げて再開する)

**<font color="red">環境にvagrant-dockerを使用しています</font>**


最新のリモートをクローンしてくる

```
[vagrant@local-docker docker-laravel]$ git clone https://github.com・・・・/・・・・.git
```

クローンが終わればファイルがあるか確認（必要ならmvコマンドで名前を変更）
※ここではlara-dというファイル名で進めます

```
[vagrant@local-docker docker-laravel]$ ls
README.md   docker-compose.yml  lara-d
apache-php  index.php           
```

lara-d に移動

```
[vagrant@local-docker docker-laravel]$ cd lara-d
```

今どのブランチにいるかを確認
 
```
[vagrant@local-docker lara-d]$ git branch
* master
```

ここで、最新のリモートdevelop_alphaブランチをpullしてくる(ここではdevelop_alphaというリモートのメインブランチ)

```
[vagrant@local-docker lara-d]$ git pull origin develop_alpha
・・・・・
・・・・
・・
//pullが完了
```

Lara-dでdockerを再起動する

```
[vagrant@local-docker lara-d]$ docker-compose restart
Restarting apache-php   ... done
Restarting phpmyamin-la ... done
Restarting mysql5.7     ... done
```

webコンテナ内に入る

```
[vagrant@local-docker lara-d]$ docker-compose exec web bash
```

Composerが入っていないので新しくインストールする
これがおそらく新しくプロジェクトを始める際のに必要な手順？

```
[root@1b08bc3fd4bf html]# composer install
・・・・・
・・・・
・・
//composerのインストール完了
```

Git logを確認
→みんなのlogが確認できれば正しくpullできているということ(?)

```
[vagrant@local-docker lara-d]$ git log
・・・・・
・・・・
・・
//logが存在していれば成功
```

ブランチを確認→なぜかdevelop_alphaブランチがない

```
[vagrant@local-docker lara-d]$ git branch
* master
```

develop_alphaブランチに移動してみる

```
[vagrant@local-docker lara-d]$ git checkout develop_alpha
D	.env.example
Branch develop_alpha set up to track remote branch develop_alpha from origin.
Switched to a new branch 'develop_alpha'
```

あった！！

```
[vagrant@local-docker lara-d]$ git branch
* develop_alpha
  master
```

**--ここから続きの開発を始めることができる--**