Laravel基本内容のまとめ２

#はじめに
前回の投稿の続きで、Laravelのこれだけは知っておいた方がいいと思う内容をまとめてみました。
前回の投稿である「Laravel基本内容のまとめ１」は[こちら](https://qiita.com/WorldLab5/items/a98c9971c89c913adb61)

#4.フロントエンド

###ビュー
ビューはBladeテンプレートを使うため、拡張子は「.blade.php」になります。
コントローラからデータを渡す時は、viewヘルパの第2引数で設定します。
{{ }}で囲むと、XSS攻撃を防ぐために、htmlspecialchars関数を通して、PHP変数の値を表示することができるようになります。
ビュー上でエスケープしたくない時は、{!! !!}で囲みます。

```php:TestController.php
return view('hello', ['name' => 'tanaka']);
```
```php:hello.blade.php
Hello, {{ $name }}
Hello, {!! $name !!}
```
###Blade(継承・セクション)
@extendsで引数に指定したテンプレートを継承することができます。
継承元のテンプレートで@yieldを記載した箇所に、拡張テンプレートの@sectionの内容が挿入されます。

```php:base.blade.php
<body>
  @yield('content')
</body>
```
```php:main.blade.php
@extends('base')
@section('content')
  メインコンテンツを記載
@endsection
```

###Blade(インクルード)
@includeを使用することで他のテンプレートを取り込むことができます。
親のビューの全データ変数が取り込み先のビューに継承されますが、追加のデータを配列で渡すこともできます。

```php:test.blade.php
@include('templete.part')
@include('templete.part', ['name' => 'tanaka'])
```
###Blade(if文)
PHPの構文と同じif文で表示内容を切り替えることができます。

```php:test.blade.php
@if (count($records) === 1)
  1レコード
@elseif (count($records) > 1)
  複数レコード
@else
  Noレコード
@endif
```
###Blade(switch文)
PHPの構文と同じswitch文で表示内容を切り替えることができます。

```php:test.blade.php
@switch($count)
  @case(1)
    ケース１の処理
    @break
  @case(2)
    ケース２の処理
    @break
  @default
    デフォルトの処理
@endswitch
```
###Blade(for文・foreach文)
PHPの構文と同じfor文、foreach文で繰り返しの表示処理ができます。

```php:test.blade.php
@for ($i = 0; $i < 10; $i++)
  <div>i : {{ $i }}</div>
@endfor

@foreach ($users as $user)
  <div>ユーザ名 : {{ $user->name }}</div>
@endforeach
```
###Blade(PHP文)
PHPの処理を直接記載することもできます。

```php:test.blade.php
@php
  $i = 10;
@endphp
```
###Blade(CSRFフィールド)
悪意のあるリクエスト送信を防ぐために、CSRF保護ミドルウェアがデフォルトで実装されており、リクエスト時にはCSRFフィールドが必要になります。

```php:test.blade.php
<form method="POST" action="/profile">
  @csrf
  //
</form>
```
###バリデーションエラー
バリデーションに失敗すると$errors変数にエラー情報が格納されるようになります。
下記のようにすることでエラーメッセージを表示することができます。
old関数を使うと入力時の値をバリデーション失敗時に表示することができます。

```php:test.blade.php
<input type="text" class="form-control @if($errors->has('name')) is-invalid @endif"
id="name" name="name" value="{{ old('name') }}">
<div class="invalid-feedback">
  {{ $errors->first('name') }}
</div>
```
###多言語化
「config/app.php」ファイルにある、'locale' => 'en'を、'locale' => 'ja'に修正することで、デフォルトで日本語ファイルを読み込めるようになります。
「resources/lang/ja」ディレクトリを作成し、その配下に日本語用の文字列ファイル(messages.php)を作成します。

```php:messages.php
<?php
return [
  'email' => 'メールアドレス',
  'password' => 'パスワード',
];
```

```php:test.blade.php
{{ __('messages.email') }}
@lang('messages.email')
```

#5. データベース
###モデル
モデルはデータベーステーブルと関連しており、テーブル1つにつき、1つのモデルを作成します。
モデル名の複数形をスネークケースにしたものが、テーブル名になるというのが基本的な命名規則になっていますが、モデルのtableプロパティで任意のテーブル名を指定することもできます。
ソフトデリートトレイト(use SoftDeletes;)を使用すると、論理削除することができ、guardedプロパティは複数代入したくない属性の配列を指定します。
「php artisan make:model モデル名」コマンドで、Model拡張クラスが作成されます。

```php
class Flight extends Model
{
  use SoftDeletes;

  protected $table = 'my_flights';
  public $guarded = [
    'id',
  ];
}
```

###リレーション
データベーステーブルのリレーションをモデルに定義します。
1対1の場合は、hasOneメソッドで対象となるモデルクラスを指定します。
1対多の場合は、hasManyメソッドで多に相当するモデルクラスを指定し、belongsToメソッドで従属するモデルクラスを指定します。

```php:Companyクラス(1)
class Company extends Model
{
  public function phone()
  {
    return $this->hasOne(Phone::class);
  }
  public function employees()
  {
    return $this->hasMany(Employee::class);
  }
}
```

```php:Employeeクラス(多)
class Employee extends Model
{
  public function company()
  {
    return $this->belongsTo(Company::class);
  }
}
```

###マイグレーション
「database/migrations」ディレクトリ配下にマイグレーション用のファイルを作成します。
Schema::createメソッドやSchema::dropメソッドの第1引数がテーブル名になり、createメソッドのfunction内で、テーブルのカラム名やカラムの型を全て記載します。
timestampsメソッドは更新日時(updated_at)や削除日時(deleted_at)が生成されます。
ファイル作成後に、「php artisan migrate」コマンドで全てのテーブルを作成することができます。

```php
class CreateFlightsTable extends Migration
{
  public function up()
  {
    Schema::create('flights', function (Blueprint $table) {
      $table->bigIncrements('id');
      $table->string('name');
      $table->timestamps();
    });
  }

  public function down()
  {
    Schema::drop('flights');
  }
}
```

###モデルファクトリー
「database/factories」ディレクトリ配下にモデルファクトリー用のファイルを作成します。
ファクトリーではFakerを使用してデータ自動生成時のルールを設定することができます。

```php
use App\Models\Company;

$factory->define(Company::class, function (Faker $faker) {
  return [
    'code' => Str::random(10)
    'name' => $faker->company
    'id' => $faker->numberBetween(1, 9999)
    'text' => $faker->text(10),
    'phone' => $faker->phoneNumber,
  ];
});
```

###シーダー
「database/seeds」ディレクトリ配下にシーダー用のファイルを作成します。
factoryクラスの第2引数で自動生成するレコード数を指定し、createメソッドをコールすることで、テーブルデータの自動生成が行われます。
「php artisan db:seed」コマンドで、DatabaseSeederクラスが実行されます。

```php
class DatabaseSeeder extends Seeder
{
  public function run()
  {
    factory(Company::class, 10)->create();
  }
}
```

#6. Eloquent(ORM)
EloquentとはLaravel標準のORMであり、モデルを使ってテーブルデータをクエリできます。

###取得
全レコードを取得したい時はallメソッドを使用します。firstメソッドは最初に該当する1レコードのみ取得します。
where、whereIn、whereBetweenメソッド等で条件を絞り、getメソッドで条件に該当する全てのレコードを取得できます。
count、max、sumといった集計関数も使用できます。

```php
$flights = Flight::all();
$flight = Flight::where('id', 1)->first();
$flights = Flight::whereIn('id', [1, 2, 3])->orderBy('name', 'desc')->get();
$flights = Flight::whereBetween('votes', [1, 100])->orderBy('name', 'desc')->get();

$count = Flight::where('id', '>', 100)->count();
$max = Flight::where('active', 1)->max('price');
```

###Insert
createメソッドを使ってレコードが挿入されます。挿入に成功すると、挿入したレコードのオブジェクトが返却されます。

```php
$user = User::create([
  'first_name' => 'takuro',
  'last_name' => 'tanaka',
  'age' => 22,
]);
```

###Update
updateメソッドを使うと、該当するレコード全ての情報を更新することができます。
saveメソッドでも更新することができ、saveメソッドでは、条件に該当するレコードがない場合にレコードが挿入されます。

```php
Flight::where('destination', 'Tokyo')->update(['delayed' => 1]);

$flight = App\Flight::find(1);
$flight->name = 'A007';
$flight->save();
```

###Delete
モデルを削除する時は、deleteメソッドを使います。deleteメソッドは、クエリに該当するレコード全てに対して適用されます。
destroyメソッドを使うと、主キー指定で削除することができます。
モデルにソフトデリート(use SoftDeletes;)が有効になっている場合は、論理削除され、deleted_atカラムに削除した時間が設定されます。
指定したモデルインスタンスがソフトデリートされているかを確認するには、trashedメソッドを使います。

```php
Flight::where('active', 0)->delete();
Flight::destroy(1);
Flight::destroy(1, 2, 3);

$isTrashed = $flight->trashed();
```

#7. コレクション
Eloquentがgetメソッド等で複数のレコードをリターンした場合、Collectionクラスのオブジェクトが返却されます。
Collectionクラスを使用すると、データの解析や操作に役立ちます。

###取得
* firstメソッド・・条件に該当する最初のデータ1件を返却
* whereメソッド・・条件に該当するデータを返却
* whereInメソッド・・指定した値が含まれるデータを返却
* whereNotInメソッド・・指定した値が含まれないデータを返却
* keysメソッド・・キー名のみを返却
* countメソッド・・該当するデータ数を返却
* filterメソッド・・条件に一致する要素を返却
* rejectメソッド・・条件に一致しない要素を除いて返却

```php
$users = User::where('active', 1)->get();

$item = $users->where('name', 'tanaka')->first();
$items = $users->whereIn('age', [10, 20, 30]);
$items = $users->whereNotIn('age', [10, 20, 30]);
$keys = $users->keys();
$count = $users->count();
$filtered = $users->filter(function ($value, $key) {
  return $value->age >= 20;
});
$filtered = $users->reject(function ($value) {
  return $value->age < 20;
});
```

###ソート・変換・抽出
* sortByメソッド・・指定したキーでソートして返却
* groupByメソッド・・指定したキーでグループ化して返却
* pluckメソッド・・指定したキーのみのデータで返却
* onlyメソッド・・指定したキーを持つ要素のみを返却
* exceptメソッド・・指定したキー以外を持つ要素のみを返却
* mapメソッド・・全てのデータに対して処理を行う
* toArrayメソッド・・配列へ変換する

```php
$users = User::where('active', 1)->get();

$sorted = $users->sortBy('age');
$grouped = $users->groupBy('country')->toArray();
$plucked = $users->pluck('country');
$filtered = $users->only('name', 'age');
$filtered = $users->except('phone');
$filtered = $users->map(function ($value, $key) {
  return $value->country = 'Ja';
});
```

以上です。