前提
コマンドライン
アプリ作る
curl -s "https://laravel.build/アプリ名" | bash
sail立ち上げ
./vendor/bin/sail up
sail 〇〇 が使えるようにする
alias sail='[ -f sail ] && sh sail || sh vendor/bin/sail'
breez(全部のっけ的なスターターキット)
sail composer require laravel/breeze --dev sail artisan breeze:install sail artisan migrate sail npm install sail npm run dev
日本語化
sail composer require askdkc/breezejp --dev sail artisan breezejp
モデル作成(マイグレーション付き)
sail artisan make:model Post -m
マイグレートする
sail artisan migrate
マイグレートしたやつを戻す
sail artisan migrate:rollback
マイグレーションファイル追加(カラム追加)
sail artisan make:migration add_column_user_id_to_posts_table --table=posts
コントローラー作成(resource付き)
sail artisan make:controller PostController --resource --model=Post
コンポーネント作成
sail artisan make:component Message
tinker
モデル全件取得
$posts = \App\Models\Post::all();
モデル1件取得
$post = \App\Models\Post::find(1);
モデルに何のカラムが入ってるか見る
\Illuminate\Support\Facades\Schema::getColumnListing('posts');
モデル
belongsTo
<?php public function user() { return $this->belongsTo(User::class); }
hasMany
<?php public function posts() { return $this->hasMany(Post::class); }
submitで受け付けるパラメーターを設定
railsのpermit的なやつか。モデルに書くんだねえ
<?php protected $fillable = [ 'title', 'body', 'user_id', 'image', ];
コントローラー
インスタンスを作る
<?php $post=new Post();
インスタンスに代入(自動で、認証ユーザーのIDを取得)
この辺勉強中だが、Laravelってこのあたりのユーザー認証系が、標準で組み込まれてるみたい。この辺はRailsよりもかなりとっつきやすいのでは。
<?php $post->user_id=auth()->user()->id;
インスタンスをデータベースに保存
<?php $post->save();
リダイレクト
<?php return redirect()->route('post.create');
メッセージ表示
<?php return redirect()->route('post.create')->with('message', '投稿を作成しました');
バリデーション
<?php $inputs=$request->validate([ 'title'=>'required|max:255', 'body'=>'required|max:1000', 'image'=>'image|max:1024' ]); $post=new Post(); $post->title=$inputs['title']; $post->body=$inputs['body']; //以下略。ちなみに、インスタンス作成時にわざわざinputsに置き換える必要もない
ビュー
中身にするには
上記の続き。各ビューは、下記タグで囲む。
<?php <x-app-layout> </x-app-layout>
フォーム
- このケースは、postコントローラーのstoreアクションを使う
- @csrfを入れることで、クロスサイトリクエストフォージェリ(Webアプリケーションのユーザーが意図しないリクエストを偽造し、ユーザーが意図しない処理を実行させる攻撃)を防ぐ
<?php <form method="post" action="{{route('post.store')}}" enctype="multipart/form-data"> @csrf
コンポーネントを使う(breez標準付属のprimary-button)
<?php <x-primary-button class="mt-4"> 送信する </x-primary-button>
コンポーネントのコンストラクター設定
Messageというコンポーネントの場合。下記はMessage.phpに書く。オブジェクト指向のコンストラクターですな。あ、「コンポーネントのコンストラクター」って「長久命の長助さん」っぽいな
<?php public $message; public function __construct($message) { $this->message = $message; }
コンポーネント本体
上記の続き(上記とセットでコンポーネントを作るのが基本のやり方)。下記はmessage.blade.phpに書く。issetは、変数が存在するかの真偽値を返すphpの組み込み関数。Railsだとこんなの付けなくても変数だけ書いたんでよかったような・・。exist?か。いかん、この辺の理解が浅いな。戻り値をどうするかで使い分けるんだっけ。trueではなかったときにnilかfalseかというところで。
<?php @if(isset($message)) <div> {{$message}} </div> @endif
コンポーネントを使用する
- タグで囲んだ場合は、コンポーネント本体のslot部分が、「コンポーネントを指定したビュー内のタグで囲われてる部分」に置き換わるという理解。
- タグで囲わなかったら、まるっとコンポーネントに置き換わるという理解。
<?php // <x-ファイル名> </ファイル名> // <x-ファイル名 :データ名=データの定義> </ファイル名> // <x-ファイル名 :データ名=データの定義 /> <x-message :message="session('message')" />
匿名コンポーネント
上記の例でいくと、コンストラクター用のMessage.phpを作らず、message.blade.phpだけを作ること。使用の仕方は上記と同じ。
<?php @props(['message']) @if(isset($message)) <div> {{$message}} </div> @endif
標準コンポーネント(バリデーションエラー)
<?php <x-input-error class="mb-4" :messages="$errors->all()"/>
バリデーションエラー後、入力したものを自動入力してくれる
これもRailsのform_withだと標準ではあるけど、こっちの方が明示的で好感が持てるなあ。ほんまform_with嫌い。書き方が柔軟すぎて。
<?php value="{{old('title')}}"
コンポーネント(カスタマイズしたバリデーションエラー)
Laravel教科書では、画像を再添付させるためにカスタムコンポーネントを使用している。注意書きレベルのものをエラーと同じ文字装飾で表示するのってどうなんだろう。なんか引っかかるなあ。
<?php @props(['errors']) @if ($errors->any()) <div {{ $attributes }}> <div class="font-medium text-red-600"> エラーの内容を確認してください。 </div> <ul class="mt-3 list-disc list-inside text-sm text-red-600"> @foreach ($errors->all() as $error) <li>{{ $error }}</li> @endforeach @if(empty($errors->first('image'))) <li>画像ファイルがあれば、再度、選択してください。</li> @endif </ul> </div> @endif
ルーティング
resource
<?php Route::resource('post', PostController::class);
上記を分解
<?php Route::get('post', [PostController::class, 'index'])->name('post.index'); Route::get('post/create', [PostController::class, 'create'])->name('post.create'); Route::post('post', [PostController::class, 'store'])->name('post.store'); Route::get('post/{post}', [PostController::class, 'show'])->name('post.show'); Route::get('post/{post}/edit', [PostController::class, 'edit'])->name('post.edit'); Route::patch('post/{post}', [PostController::class, 'update'])->name('post.update'); Route::delete('post/{post}', [PostController::class, 'destroy'])->name('post.destroy');
マイグレーションファイル
モデル新規作成時にカラムを設定
nullableとすると、必須ではなくなる。これ、もしかしてバリデーション的なものなのか?この辺は勉強。
<?php $table->string('title'); $table->text('image')->nullable();
foreignId
ここもよく分からん。integerではないのは、他のモデルのidを使うからか?それともbelongsしてるからか?
<?php $table->foreignId('user_id');
特定のカラムの後に追加
一発目のマイグレート以降のカラム追加時に使う。
<?php $table->foreignId('user_id')->after('image');