LoginSignup
21
29

More than 3 years have passed since last update.

Laraveの知識をアウトプットして、資産化してます

Last updated at Posted at 2020-05-15

新規プロジェクト

まずはプロジェクトの作成をしていきます。

よく使うコマンド
$ composer create-project laravel/laravel sampleproject --prefer-dist "6.0.*"

個人的に上記のコマンドでバージョンを指定してプロジェクトを作成します。
sampleprojectの箇所がプロジェクト名となります。
書き方は他にもいろいろあります。

ターミナル
# バージョン指定なし (最新版をインストール, 初期値でmysqlを利用する)
$ composer create-project --prefer-dist laravel/laravel プロジェクト名

# バージョン指定あり (初期値でmysqlを利用する)
$ composer create-project --prefer-dist "laravel/laravel=5.5.*" sampleproject

#書き方はいろいろ
$ composer create-project laravel/laravel sampleproject --prefer-dist "6.0.*"

初期設定

続いては初期設定をしていきます。
時間や地域、言語などを日本にしていきましょう。

暗号化

コマンド
php artisan key:generate

[Laravel5.5] APP_KEY の行方を追う

タイムゾーンを日本に変更

タイムゾーンの変更

config/app.php

'timezone' => 'UTC',
#UTCをAsia/Tokyoに変更
'timezone' => 'Asia/Tokyo',

言語を日本に変更

config/app.php

'locale' => 'en',
#enをjaに変更
'locale' => 'ja',

フェイカーもを日本語に設定

config/app.php

#before
'faker_locale' => 'en_US',

#after
'faker_locale' => 'ja_JP',

DBの文字設定

これに関しては変更しなくても大丈夫です。

config/database.php
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',

#mb4を消す(顔文字を不要)
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',

デバックバーのインストール

ターミナル
$ composer require barryvdh/laravel-debugbar

画面上に非表示にするために、.envファイルを変更する

.env
APP_DEBUG=true
#falseに変更する
APP_DEBUG=false

これでも画面に残っている場合は、キャッシュを消す

ターミナル

php artisan cache:clear
php artisan config:clear
php artisan route:clear
php artisan view:clear

何かと反映しないときは、上記コマンドでキャッシュを削除して反映させるので、よく使います。

tinkerのインストール

tinkerの使い方
公式ドキュメント

tinkerは処理を確認する際に使います。デバックの一つの方法です。

tinkerの導入
$ composer require laravel/tinker
tnker起動コマンド
$ php artisan tinker
Taskの一覧を取得する
$ php artisan tinker


>>> Task::all();

他にもあります

DBの設定変更

.envファイルの下記のDB設定における、DATABASE名、USERNAM名、PWを設定していく

.env
//アプリ名の変更
APP_NAME=Laravel


//DB情報を変更する
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel
DB_USERNAME=laravel
DB_PASSWORD=

MAMPでDBの作成

Image from Gyazo

MAMPでUSERを作成

Image from Gyazo

作成した情報を記述する

.env
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306 #MAMP上で設定されたlocalhostになる
DB_DATABASE=laravel_task
DB_USERNAME=laravel_user
DB_PASSWORD=password

MAMPのローカルホストを変更する場合

接続できるか確認

ターミナル
$php artisan migrate

成功した場合は、無事にDBに接続できている。

MAMPのDBをSeaquel Proで確認する場合

ユーザー名:root
パスワード:root
データベース:
ソケット:/Applications/MAMP/tmp/mysql/mysql.sock
スクリーンショット 2020-05-14 12.31.00.png

これで接続すれば、確認ができる

Laravel-ui認証

マニュアルページを開く

laravel/uiパッケージをインストール(laravel6)

//laravel6の場合
$ composer require laravel/ui:^1.0 --dev
$ composer require laravel/ui "1.*"

//laravel7の場合
$ composer require laravel/ui:^2.4 --dev
$ composer require laravel/ui "2.*"
フロントエンドのスカフォールドをインストール
// 基本的なスカフォールドを生成
php artisan ui bootstrap
php artisan ui vue
php artisan ui react

// ログイン/ユーザー登録スカフォールドを生成
php artisan ui bootstrap --auth
php artisan ui vue --auth
php artisan ui react --auth
vue.js+bootstrapの場合
$ composer require laravel/ui
$ php artisan ui vue --auth
$ npm install bootstrap-vue bootstrap

import BootstrapVue from 'bootstrap-vue';
Vue.use(BootstrapVue);

参考ページはこちら

依存パッケージのインストール
$ npm install && npm run dev
補足
$ npm run dev ・・開発用にビルド
$ npm run watch ・・常時ビルド
$ npm run prod ・・本番用にビルド

新規登録後の移行先を変更

RegisterControll.php
#before homeを消す
protected $redirectTo = '/home';

#after
protected $redirectTo = '/';

ログイン後の移行先を変更

laravel6の場合

loginControll.php
#before homeを消す
protected $redirectTo = '/home';

#after
protected $redirectTo = '/';

larvel6.8以降の場合

laravel6.8以降は、よりDRYになっている。

php/RouteServiceProvider.php
<?php
// 略
class RouteServiceProvider extends ServiceProvider
{
    // 略 
    public const HOME = '/home';

ここでHOMEを定義することで、複数のAuth系のコントローラーで反映される。

app/Http/Controllers/auth/LoginController.php
<?php
// 略 
class LoginController extends Controller
{
    // 略
    protected $redirectTo = RouteServiceProvider::HOME;
    // 略
}

エラーメッセージを日本語化

コマンドでやる場合

$ php -r "copy('https://readouble.com/laravel/6.0/ja/install-ja-lang-files.php', 'install-ja-lang.php');"
$ php -f install-ja-lang.php
$ php -r "unlink('install-ja-lang.php');"

下記リンクを開く
https://github.com/minoryorg/laravel-resources-lang-ja

ファイルをダウンロード
Image from Gyazo

ダウンロードしたフォルダを開くと、jaというフォルダが存在する
スクリーンショット 2020-05-15 11.05.12.png

resources/langフォルダに、ダウンロードしたjaフォルダを追加
スクリーンショット 2020-05-15 11.10.13.png

これで日本語されています
passwordなど英語表記のものを日本語にするには、

validation.php
'attributes' => [],
//最下部のattributesにパスワードの項目を追加する

'attributes' => [
        'password'=>'パスワード'
    ],

ターミナルで開いておきたい

ターミナル(タブ1)
$ npm run development -- --watch
ターミナル(タブ2):ローカルサーバー
$ php artisan serve
ターミナル(タブ3):コマンド実行用
$ 何かターミナルコマンド入力する際に利用する

特定の環境のwebpackでは、ファイル変更時に更新されないことがあります。自分のシステムでこれが起きた場合は、watch-pollコマンドを使用してください。

$ npm run watch-poll

font-awesomeをインストール

コマンド
$ npm install --save-dev @fortawesome/fontawesome-free

MVCの操作

ここからMVCコントローラーの操作を進めていく

モデル

モデルの作成

一番便利なコマンド
# Post関連など全て作成する場合は、下記が一番便利(all)
$ php artisan make:model Models/Post -a

上記コマンドを実施すると、コンとローラー、マイグレーションファイル、seeder、factory、テストが生成される。どちらにせよこれらは利用するので、基本このコマンドを使うと良い。

補足として、他のコマンドを紹介しておきます。

ターミナル

#モデル単体を作成
$php artisan make:model Models/Test

# モデル、マイグレーションファイル、コントローラーを同時に作成
$ php artisan make:model Models/Test -mc

#コントローラーの作成(基本的なアクション含む)
php artisan make:controller PhotoController --resource

Models/Test Modelsフォルダの中で、Test.phpを作成
-mcはマイグレーションファイルとコントローラーを同時に作成するオプション

マイグレーション

マイグレーションファイルの作成

ターミナル
$php artisan make:migration create_tests_table

#追加で作成
php artisan make:migration add_user_id_to_posts_table --table=posts

マイグレーションの記述

マニュアル
https://readouble.com/laravel/6.x/ja/migrations.html
マニュアルを参考に、カラム型、制限をかけて、カラム修飾子で詳細に設定する

MySQLの外部キー制約RESTRICT,CASCADE,SET NULL,NO ACTIONの違いは?

カラム

_create_tweet_table.php
Schema::create('tweets', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('title', 200); #200文字制限
            $table->unsignedBigInteger('user_id');
            $table->foreign('user_id')->references('id')->on('users');
            $table->text('text');
            $table->timestamps();
        });

マイグレーションを実行

マイグレーションを実行
$ php artisan migrate
マイグレーションの履歴を確認
$php artisan migrate:status
マイグレーションをロールバックする
$php artisan migrate:rollback --step=5

$fillable(ホワイトリスト)

カラム情報をcreateや更新などしてよいか許可する。これをしないとエラーが発生する。

Post.php
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class post extends Model
{
    protected $fillable = [
        'title', 'body', 'user_id'
    ];

}

カラムの変更

参考になるページ1
参考になるページ2

「up」の中にはテーブル作成時の記述、「down」の中にはテーブル削除時の記述を書きます。

Schema::createではなく、Schema::tableを記述して変更する

準備

インストール
コマンド
$ composer require doctrine/dbal

上記コマンドをしない場合は下記のエラーが表示される

エラー
[RuntimeException]                                                                   
  Changing columns for table "books" requires Doctrine DBAL; install "doctrine/dbal".
変更用のマイグレーションファイルを作成

変更用のmigrationファイルを作成する。

コマンドの例
$ php artisan make:migration change_books_table --table books
コマンド例
$ php artisan make:migration modify_users_table --table=users

カラム名の変更

renameColumnを利用する

変更用のファイル
public function up()
{
    Schema::table('users', function (Blueprint $table) {
        $table->renameColumn('from', 'to');
    });
}

カラム属性の変更

DBを削除して、再度マイグレーションするのも一つではあるが、この例ではあくまで既存のDBのカラム名を変更するやり方とする。

作成したファイルに変更内容を記述する。
->change();で変更する

change_books_table
public function up()
{
    Schema::table('books', function (Blueprint $table) {
        $table->datetime('published')->change();
    });
}
公式の例
Schema::table('users', function (Blueprint $table) {
    $table->string('name', 50)->change();
});

カラムを削除

dropColumnを利用する

カラム削除時の記述
Schema::table('users', function (Blueprint $table) {
    $table->dropColumn('votes');
});

再度に更新させる

コマンド
$ php artisan migrate

すべてのmigrationをリセットする

migrate:resetコマンドはアプリケーション全部のマイグレーションをロールバックします。

$ php artisan migrate:reset

これを実施後に既存のmigrationファイルを書き換えれば良い。

リレーション

マニュアル
User.phpのパスを変更する場合

1対多

外部キーがデフォルトの<テーブル名_id>の場合

namespace <ファイルのパス>

tweet.php
<?php

namespace App\Model;  //フォルダの階層

use Illuminate\Database\Eloquent\Model;

class Tweet extends Model
{
    public function user() #userとのリレーションを定義。belongs = 単数
    {
        return $this->belongsTo('App\User');
    }
    public function comments() #commentとのリレーションを定義。hasMany = 複数
    {
        return $this->hasMany('App\Model\Comment');
    }
}

上記ではModelを利用するために、namespace App\Model;use Illuminate\Database\Eloquent\Model;でモデルクラスを呼び出している。だから、class Tweet extends Modelとextendsで継承できる

user.php
<?php

namespace App;

use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;

class User extends Authenticatable
{
    public function tweets()
    {
        return $this->hasMany('App\Model\Tweet');
    }
    public function comments()
    {
        return $this->hasMany('App\Model\Comment');
    }

    use Notifiable;

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name', 'email', 'password',
    ];

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        'password', 'remember_token',
    ];

    /**
     * The attributes that should be cast to native types.
     *
     * @var array
     */
    protected $casts = [
        'email_verified_at' => 'datetime',
    ];


}

外部キーの名前がデフォルトの<テーブル名_id>でない場合

foreign_keyは<テーブル名_id>でない場合(カスタムしている場合)

ポイントは、外部キーのカラム名を指定してあげること。

`hasMany('モデルの場所', '<テーブル名_id>でない場合は、外部キーの指定', '参照先テーブルのカラムがidでない場合、カラムを指定')

デフォルトだと、
- user_idtweet_idなどの<テーブル名_id>を外部キーとして参照する。
- 参照先テーブルのidを取得する

だから、デフォルトの外部キーとカラムが違う場合は、それぞれ指定する必要がある。

所得先が"id"の場合は、local_idを省略
公式情報
return $this->hasMany('App\Comment', 'foreign_key');

公式情報のforeign_keyの箇所に指定の外部キーを記述する。

return $this->hasMany('App\User', 'buyer_id');
return $this->hasMany('App\User', 'seller_id');

上記の例のように、指定の外部キーを記述する。

具体的に見てみましょう

Product.php
<?php

namespace App\Model;

use Illuminate\Database\Eloquent\Model;

class Product extends Model
{
    public function seller()
    {
        return $this->belongsTo('App\User', 'seller_id'); //seller_idと一致するUserを取得する
    }
}

User.php
class User extends Authenticatable
{
    public function sell_products()
    {
        return $this->hasMany('App\Model\Product', 'seller_id'); //productの中でseller_idがこのUserのidと一致するものを取得する
    }
}
所得先が"id"でない場合は、local_idを指定

ようするに、デフォルトの"id"を参照しないので、どのカラムを指定するのかオプションで指定する。

公式情報
return $this->hasMany('App\Comment', '外部キーのカラム名', 'カラム名');

上記を指定すればよい。
あまり使うことはないと思うが、簡単に例を出す。

デフォルトだとid
return $this->hasMany('App\Product', 'seller_id', 'id');

デフォルトだとidを参照する。しかしidではなく、product_numberを取得するとしたら、

公式情報
return $this->hasMany('App\Product', 'seller_id', 'product_number');

上記のように記述する。

多対多

公式ページ

belongsToManyを利用して、多対多を定義する。

基本
belongsToManyの引数
return $this->belongsToMany('紐付けるモデル', '中間テーブル', '中間テーブルのこのモデル_id', '中間テーブルの紐付け先モデル_id');

第 1 引数では最終的な接続先モデル名を名前空間含めて指定する
第 2 引数では中間テーブル名を指定する
第 3 引数では接続元モデル ID を示す中間テーブル内のカラム名を指定する
第 4 引数では最終的な接続先モデル ID を示す中間テーブル内のカラム名を指定する
第 5 引数では接続元モデル ID のカラム名を指定する
第 6 引数では最終的な接続先モデル ID のカラム名を指定する

公式ページ
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * userに所属する役目を取得
     */
    public function roles()
    {
        return $this->belongsToMany('App\Role', 'role_user', 'user_id', 'role_id');
    }
}
マイグレーション

*他の例**

  • productモデル(リレーションの定義:必須)
  • product_tagモデル(中間テーブル、リレーションの定義:不要)
  • tagモデル(リレーションの定義;必須)

上記のモデルがあるとする。

それぞれのマイグレーションファイルを記述する

多となるProductのマイグレーションファイル

_create_product_table.php
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateProductsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('products', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('title');
            $table->text('text');
            $table->unsignedBigInteger('user_id');
            $table->foreign('user_id')->references('id')->on('users');
            $table->timestamps();
        });
    }


もう一方の多となるTag

_create_Tab_table.php
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateTabsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('Tabs', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('name');
            $table->timestamps();
        });
    }

ProductとTagを紐づける、中間テーブルproduct_tag
これに関しては外部キーで紐付けてあげればよい。

_create_product_tag_table.php
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateProductsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('products', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->unsignedBigInteger('product_id');
            $table->foreign('product_id')->references('id')->on('products');
            $table->unsignedBigInteger('tag_id');
            $table->foreign('tag_id')->references('id')->on('tags');
            $table->timestamps();
        });
    }
エラー
#SQLSTATE[HY000]: General error: 1215 Cannot add foreign key constraint

結論: 外部キーをもつモデルを先に削除しなさい

下記の例は、postの外部キーをもつcommentのmigrationファイルです。
この場合、postより先にcommentモデルを削除する必要がある。
なので、そのように設定する。

_create_post_tags_table.php
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreatePostTagsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('post_tags', function (Blueprint $table) {
            $table->increments('id');
            $table->unsignedInteger('tag_id');
            $table->unsignedInteger('post_id');
            $table->foreign('tag_id')->references('id')->on('tags')->onDelete('cascade');
            $table->foreign('post_id')->references('id')->on('posts')->onDelete('cascade');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('post_tags'); 
        Schema::dropIfExists('posts'); //下に親モデル
        Schema::dropIfExists('tags');  //下に親モデル
    }
}


焦点をあててみると、

ここ
    public function down()
    {
        Schema::dropIfExists('post_tags'); 
        Schema::dropIfExists('posts'); //下に親モデル ここ
        Schema::dropIfExists('tags');  //下に親モデル ここ
    }

外部キーの親モデルを下に書けばよい。

同様に親モデル側のmigrationにも書いていきます。

_create_post_table.php
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreatePostsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->increments('id');
            $table->string('title', 50);
            $table->text('body');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('post_tags');
        Schema::dropIfExists('posts');
    }
}

create_tags_table.php
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateTagsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('tags', function (Blueprint $table) {
            $table->increments('id');
            $table->timestamps();
            $table->string('name');
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('post_tags');
        Schema::dropIfExists('tags');
    }
}

#SQLSTATE[42S01]: Base table or view already exists: 1050 Table 'posts' already exists

このエラーが発生した場合は、一度リセットしなおせば良い。

$php artisan migrate:refresh

これで改善します。

あとは、リレーションを記述する。

リレーションの記述

productとtagのリレーションだけ記述すればいいので、難しくない。

Product.php
<?php

namespace App\Model;

use Illuminate\Database\Eloquent\Model;

class Product extends Model
{
    public function tags()
    {
        return $this->belongsToMany('App\Models\Tag', 'product_tag'); 
    }
}
Tag.php
<?php

namespace App\Model;

use Illuminate\Database\Eloquent\Model;

class Product extends Model
{
    public function products()
    {
        return $this->belongsToMany('App\Models\Product', 'product_tag'); 
    }
}
product_tag

// 得に記述不要

これで多対多の完成です。

save,create

参考ページ
参考

create

saveとsaveManyメソッドに加え、createメソッドも使用できます。属性の配列を引数に受け付け、モデルを作成しデータベースへ挿入します。saveとcreateの違いはsaveが完全なEloquentモデルを受け付けるのに対し、createは普通のPHPの「配列」を受け付ける点です。

create
$post = App\Post::find(1);

$comment = $post->comments()->create([
    'message' => 'A new comment.',
]);

外部キーを紐付けるとき

attach()で紐付ける
$post = Post::create($params);
$tag = Tag::firstOrCreate(['name' => $request->tags]);
$post->tags()->attach($tag);
createMany
createMany
$post = App\Post::find(1);

$post->comments()->createMany([
    [
        'message' => 'A new comment.',
    ],
    [
        'message' => 'Another new comment.',
    ],
]);
save
save
$post = App\Post::find(1);
$post->comments()->save($comment);
saveMany

複数の関連したモデルを保存する必要があるなら、saveManyメソッドを使用できます。

saveMany
$post = App\Post::find(1);

//書き方1
$post->comments()->saveMany([
    new App\Comment(['message' => 'A new comment.']),
    new App\Comment(['message' => 'Another comment.']),
]);

//書き方2
$post->comments->saveMany([ $item1 , $item2 ]);

//書き方3
$post->comments()->saveMany($comments);

ルーティング

ファイルの場所

  • web.php: 基本はここ
  • api.php: APIのルーティングはこちら

書き方

チートシート
参考になる資料

GET

web.php

Route::get('url', 'コントローラー@アクション')->name('パスの名前');

Route::get('/posts/{post}', 'PostController@show')->name('posts.show');

POST

web.php
Route::post('/',   'HomeController@post');

resource

通常
web.php
Route::resource('photos', 'PhotoCommentController');
// [GET](/photos)           ->index
// [GET](/photos/{id})      ->show($id)
// [GET](/photos/create)    ->create
// [POST](/photos)          ->store
// [GET](/photos/{id})      ->edit($id)
// [PUT/PATCH](/photos/{id})->update($id)
// [DELETE](/photos/{id})   ->destroy($id)

Route::resource('photos', 'PhotoController');

only
web.php

Route::resource('photos', 'PhotoController', [
  'only' => ['index', 'show']
]);
Route::resource('posts', 'PostsController', ['only' => ['create', 'store']]);

except
web.php

Route::resource('photos', 'PhotoController', [
  'except' => ['index', 'show']
]);

Route::resource('tweets', 'TweetController', [ 'except' => ['index', 'show']]);

ネスト
web.php

Route::resource('photos.comments', 'PhotoCommentController');
//photos/{photoId}/comments/{commentId}

middleware(ミドルウェア)
->middleware()

#ログイン認証
Route::get('profile', function() {
    // 認証済みのユーザーのみが入れる
})->middleware('auth');

Route::get('/settings/security', function () {
    // ユーザーは続けるためにパスワードの入力が必要
})->middleware(['auth', 'password.confirm']);
Route::group()
#ユーザー認証あり
Route::group(['middleware' => 'auth'], function()
{
    Route::resource('tweets', 'TweetController', [ 'except' => ['index', 'show']]);
});
Route::middleware

Route::middleware(['first', 'second'])->group(function () {
    Route::get('/', function () {
        // firstとsecondミドルウェアを使用
    });

    Route::get('user/profile', function () {
        // firstとsecondミドルウェアを使用
    });
});

マニュアル:
https://readouble.com/laravel/6.x/ja/controllers.html

ログイン認証の書き方
Route::get('/', function () {
    //
})->middleware('auth');

// 1つのルートに対して複数のミドルウェアを指定する場合
Route::get('/', function () {
    //
})->middleware('auth', 'auth2');

// 複数のルートに対して1つのミドルウェアを指定する場合
Route::group(['middleware' => 'auth'], function () {
    //
});

// 複数のルートに対して複数のミドルウェアを指定する場合
Route::group(['middleware' => ['auth', 'auth2'], function () {
    //
});

ログイン認証のマニュアルはこちら

TestController@indexでコントローラーを紐づけている。

ルーティング一覧の確認方法

routingの一覧を確認
//ターミナルで確認
$ php artisan route:list

//ファイルで確認
$ php artisan route:list > route.text

コントローラー

コントローラーの作成

ターミナル
$ php artisan make:controller TestController

コントローラーの記述

TestController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\Test; #モデルとコントローラーを紐づける
use Illuminate\Support\Facades\DB; #この記述がないとクエリビルダはエラーになります

class TestController extends Controller
{
    //
    public function index() #railsの場合はdef indexだが、 laravelの場合はpublic function index() 
    {
        $values = Test::all(); #モデルを介して、DBから情報を取得
        dd($values); #railsのbinding.pryのように取得した内容を確認できる。
        return view('tests.index', compact('values')); #ここでどのviewなのか指定して紐づける
        #つまり、最後にどのviewにどの値を持っていくか指定する。

        #user認証をコントローラーで作成する場合
        if (Auth::check()) {
            return view('test/menu');
        } else {
            // ログインしていなかったら、Login画面を表示
            return view('auth/login');
        }
    }
}

エラー

Notice: Undefined index

nullの値が混じっているとエラーになるので、対策をとる必要がある。

index

create

store

    public function store(Request $request)
    {

        //newでsaveする方法
        $tweet = new Tweet;
        $tweet->title = $request->input('title');
        $tweet->text = $request->input('text');
        $tweet->user_id = $user->id;
        $tweet->save();

        //::createでいきなり保存する方法
        $task = Task::create($request->all());

        //validateしたあとに保存する方法
        $params = $request->validate([
                'title' => 'required|max:255',
                'body' => 'required|string',
            ]);

        $post = Post::create($params);


    }
エラー

$fillableでホワイトリスト指定する
これをしておかないとエラーが発生する。

エラー
Add [name] to fillable property to allow mass assignment on
post.php

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    protected $fillable = [
        'title',
        'body',
    ];

    public function comments()
    {
        return $this->hasMany('App\Models\Comment');
    }
}

show

edit

update

更新する
    public function update(Request $request, post $post)
    {
    $params = $request->validate([
        'title' => 'required|max:255',
        'body' => 'required|string',
    ]);
    $post->fill($params)->save();

    $task->update($request->all());

    }
update()を使用
App\Flight::where('id', 1)
          ->update(['name' => $request->name]);
save()を使用
$flight = App\Flight::find(1)
$flight->name = $request->name;
$flight->save();

destroy

クエリビルダ

マニュアルはこちら

# use Illuminate\Support\Facades\DB;の記述がないとエラーになります

public function index()
    {
        $users = DB::table('users')
                ->where('votes', '>=', 100)
                ->get();

        $users = DB::table('users')
                ->where('votes', '<>', 100)
                ->get();

        $users = DB::table('users')
                ->where('name', 'like', 'T%')
                ->get();
        $users = DB::table('users')->where([
                    ['status', '=', '1'],
                    ['subscribed', '<>', '1'],
                 ])->get();

        return view('user.index', compact('users');

    }

N+1問題

::with(['comments']のようにして、リレーションを引っ張る

参考リンク
公式ドキュメント

リレーションを引っ張る

//一つの場合
public function index()
{
    $users = User::with('posts')->limit(5)->get();
    return view('user.index')->with('users', $users);
}

//複数の場合は[]でまとめる
public function index()
    {
        $posts = Post::with(['comments'])->orderBy('created_at', 'desc')->paginate(20);

        return view('posts.index', ['posts' => $posts]);
    }

リレーションをさらに引っ張る
public function index()
{
    $users = User::with('posts.comments')->limit(5)->get();
    return view('user.index')->with('users', $users);
}
結果
select * from users limit 5
select * from posts where posts.user_id in (1, 2, 3, 4, 5)
select * from comments where comments.post_id in (10, 20, 30, 40, 50)
Authの場合

User::with('departmento')->find(Auth::id());

参考リンク

where

where(複数)
    public function index(Request $request)
    {
        //
        $last_comment_id = $request->id;
        $comment = Comment::find($last_comment_id);
        // $comments = Comment::Where([
        //                             ['tweet_id', '=', $comment->tweet->id],
        //                             ['created_at', '>', $comment->created_at],
        //                         ])->orderBy('created_at', 'asc')->get();
        $comments = Comment::With(['user'])->where([
                                                    ['tweet_id', '=', $comment->tweet->id],
                                                    ['created_at', '>', $comment->created_at],
                                                    ])->orderBy('created_at', 'asc')->get()->toJson();
        return $comments;
    }

バリデーション

マニュアルはこちら
- 方法①:コントローラー上にリクエストをvalidationする
- 方法②:FormRequestにvalidationを追加して、それをリクエストして利用する。

方法1:コントローラー上でバリデーションする

$request->validate()を使ってvalidationする。

controller
public function store(Request $request)
{
    $validatedData = $request->validate([
        'title' => 'required|unique:posts|max:255',
        'body' => 'required',
    ]);

    // ブログポストは有効
}

方法2:バリデーションを記述するファイルを作成

コマンド
#モデル名だけだと、コントローラーでモデルファイルとバリデーションファイルで競合になるので注意
php artisan make:request StoreTweet
HTTP/Requests/StoreTweet.php

public function authorize()
    {
        #before
        return false;

        #after
        return true;
    }

public function rules()
    {
        return [
            // #バリデーションのルールを記述する
            'カラム名' => 'ルール1|ルール2|ルール3',
            'title' => 'required|string|max:45',
            'text' => 'required|string|max:400',
        ];
    }

StoreTweet.php
<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class StoreTweet extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            //
            'title' => 'required|string|max:45',
            'text' => 'required|string|max:400',
        ];
    }
}

作成したバリデーションをコントローラーで読み込みさせる

TweetController
use App\HTTP\Requests\StoreTweet; #バリデーションのファイルを読み込みさせる

class TweetController extends Controller
{
    #before: Request
    public function store(Request $request)

    #before: RequestをStoreTweetに変更 > バリデーションルールが適用
    public function store(StoreTweet $request)
    {
        //
        $user = Auth::user();
        $tweet = new Tweet;
        $tweet->title = $request->input('title');
        $tweet->text = $request->input('text');
        $tweet->user_id = $user->id;
        $tweet->save();
        return redirect(route('tweets.index'));

    }

エラーメッセージをviewに表示

1箇所にすべてのエラーを表示
@if ($errors->any())
    <div class="alert alert-danger">
        <ul>
            @foreach ($errors->all() as $error)
                <li>{{ $error }}</li>
            @endforeach
        </ul>
    </div>
@endif
inputの周辺でエラーを表示
@error('title')
    <div class="alert alert-danger">{{ $message }}</div>
@enderror

エラーメッセージの編集

validation.php

#型
'ルール'             => ':カラム名は〜です。',

#before
'required'             => ':attributeは必須です。',

#after
'required'             => ':attributeを入力してください。',

ダミーデータ(seeder)

[マニュアルはこちら](https://readouble.com/laravel/6.x/ja/seeding.html)

seederの作成
$ php artisan make:seeder PhotoTableSeeder

シーダクラスを書き上げたら、Composerのオートローダを再生成するために、dump-autoloadコマンドを実行する必要があります。

流れ
まず、seederのファイルを作成して記述します(後述)。
その後に、次のコマンドを実行します。

実行前コマンド
$ composer dump-autoload

これで準備ができたので、seederを実行します

全seederを実行
$php artisan db:seed

特定のseederのみを実行させたい場合

特定のseederクラスのみ実行
$ php artisan db:seed --class=UsersTableSeeder

FactoryとSeederの作成

1対多

UserのFactory

UserFactory.php
<?php

/** @var \Illuminate\Database\Eloquent\Factory $factory */
use App\User;
use Faker\Generator as Faker;
use Illuminate\Support\Str;

/*
|--------------------------------------------------------------------------
| Model Factories
|--------------------------------------------------------------------------
|
| This directory should contain each of the model factory definitions for
| your application. Factories provide a convenient way to generate new
| model instances for testing / seeding your application's database.
|
*/

$factory->define(User::class, function (Faker $faker) {
    return [
        'name' => $faker->name,
        'email' => $faker->unique()->safeEmail,
        'email_verified_at' => now(),
        'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password
        'remember_token' => Str::random(10),
    ];
});

1対多の子要素のFactory

PostFactory.php
<?php

/** @var \Illuminate\Database\Eloquent\Factory $factory */

use App\Models\Post;
use App\Models\Tag;
use Faker\Generator as Faker;

$factory->define(Post::class, function (Faker $faker) {
    //親要素のUserを取得
    $userIDs  = App\User::pluck('id')->all();
    return [
        'title'     => $faker->realText(30),
        'body'      => $faker->realText(),
        //外部キーに親要素のUserをセット(ランダム)
        'user_id'   => $faker->randomElement($userIDs),
    ];
});

LikeFactory.php
<?php

/** @var \Illuminate\Database\Eloquent\Factory $factory */

use App\Models\like;
use Faker\Generator as Faker;

$factory->define(like::class, function (Faker $faker) {
    $postIDs  = App\Models\Post::pluck('id')->all();
    $userIDs  = App\User::pluck('id')->all();
    return [
        'post_id' => $faker->randomElement($postIDs),
        'user_id' => $faker->randomElement($userIDs),
    ];
});

Seederの記述

UserSeeder.php
<?php

use Illuminate\Database\Seeder;
use App\User;

class UserSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        App\User::create([
            'name' => "test",
            'email' => "test@test",
            'email_verified_at' => now(),
            'password' => bcrypt("test1234"),
            'remember_token' => "test12345"
        ]);
        factory(User::class, 100)->create();
    }
}

1つのダミーデータを作成する

seedの作成
php artisan make:seeder UsersTableSeeder

seederのファイルを記述
1つのデータのみ作成する場合

database/seeds/UserTableSeeder.php
<?php

use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str;

class DatabaseSeeder extends Seeder
{
    /**
     * データベース初期値設定の実行
     *
     * @return void
     */
    public function run()
    {
        DB::table('users')->insert([
            'name' => Str::random(10),
            'email' => Str::random(10).'@gmail.com',
            'password' => Hash::make('password'),
        ]);
    }
}
繰り返し処理でやる場合
<?php

use Illuminate\Database\Seeder;

class TaskSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        for ($i = 1; $i <= 10; $i++) {
            Task::create([
                'title' => 'title' . $i,
                'content' => 'content' . $i,
                'person_in_charge' => 'person_in_charge' . $i,
            ]);
        }
    }
}

seeder実行時に作成されるモデルを追加

DatabaseSeeder.php
<?php

use Illuminate\Database\Seeder;

class DatabaseSeeder extends Seeder
{
    /**
     * Seed the application's database.
     *
     * @return void
     */
    public function run()
    {
        $this->call(UsersTableSeeder::class);
        $this->call(TweetSeeder::class); #追加
    }
}

実行前コマンド
composer dump-autoload
seedの実行
#すべてのseedを実行する場合
php artisan db:seed

#特定のファイルのみ実行する場合
php artisan db:seed --class=UsersTableSeeder

#一度DBをリセットする場合
php artisan migrate:fresh --seed

ファクトリーで多数のダミーデータを作成する

マニュアル

参考になる資料:
[PHP] Fakerでランダムなフェイクデータを作成する

ファクトリの生成

コマンド

#モデル指定(モデル作成時にオプション-aを利用している場合、すでに作成されます)
php artisan make:factory TweetFactory --model=Tweet


#モデル指定なし
php artisan make:factory TweetFactory

フェイカーもを日本語に設定

config/app.php

#before
'faker_locale' => 'en_US',

#after
'faker_locale' => 'ja_US',

作成したファクトリーを記述

database/factories/TweetFactory.php
use Faker\Generator as Faker;
use Illuminate\Support\Str;

$factory->define(App\User::class, function (Faker $faker) {
    #外部キーが必要な場合、user->idをpluckで取得する
    $userIDs  = App\User::pluck('id')->all();

    return [
        'name' => $faker->name,
        'email' => $faker->unique()->safeEmail,
        'email_verified_at' => now(),
        'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password
        'remember_token' => Str::random(10),
        'title' => $faker->realText(30),
        #日本語の文章はrealText
        'text' => $faker->realText(200),
        #外部キーを挿入
        'user_id' => $faker->randomElement($userIDs),
    ];
});

Fakerの例

country 国名
prefecture 都道府県
city
ward
streetAddress 町以下
postcode 郵便番号
secondaryAddress マンション名
company 会社名
userName ユーザ名
domainName ドメイン名
email メールアドレス
name 名前(姓 + 名)
lastName
firstName
firstNameMale 名(男性)
firstNameFeMale 名(女性)
kanaName 名前カナ
lastKanaName 姓カナ
firstKanaName 名カナ
firstKanaNameMale 名カナ(男性)
firstKanaNameFemale 名カナ(女性)
phoneNumber 電話番号
realText 日本語文章

pluckメソッド
外部キー制約の書き方

ファクトリーの記述をseedファイルに使用する

<?php

use Illuminate\Database\Seeder;
use Illuminate\Support\Str;
use Illuminate\Support\Facades\DB;
use App\Model\Tweet;

class TweetSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */

#before
    public function run()
    {
        //

        DB::table('tweets')->insert([
            'title' => Str::random(10),
            'text' => Str::random(20),
            'user_id' => 1
        ]);
    }
#after
    public function run()
    {
        //
        #ファクトリーでTweetモデルを200個作成する
        factory(Tweet::class, 200)->create();

    }
}

seeder実行時に作成されるモデルを追加

DatabaseSeeder.php
<?php

use Illuminate\Database\Seeder;

class DatabaseSeeder extends Seeder
{
    /**
     * Seed the application's database.
     *
     * @return void
     */
    public function run()
    {
        $this->call(UsersTableSeeder::class);
        $this->call(TweetSeeder::class); #追加することでseederが実行される
    }
}

実行する

実行前コマンド
composer dump-autoload
seedの実行
#すべてのseedを実行する場合
php artisan db:seed

#特定のファイルのみ実行する場合
php artisan db:seed --class=UsersTableSeeder

#一度DBをリセットする場合
php artisan migrate:fresh --seed

View

基本的な考え方

  1. app.blade.phpなどの土台となるhtmlを用意する。
  2. その中に、コンテンツを入れたい場所に@yieldを記述する。
  3. 他のbladeファイルは、@extendsで土台となるapp.blade.phpを呼び出す。
  4. 呼び出したら、@yieldの部分を@sectionで記述する
  5. 部分テンプレートが必要な場合は、@includeで呼び出す。

基本的な考え方2

viewファイルの指定は、
layouts.appのように.で指定する。
.で指定するのは、viewであったり、web.phpのnameなどです。

基本的な考え方3(変数)

コントローラーで変数を定義

コントローラー

$test_1 = 1;
$test_2 = 2;

return view('posts.index', compact('test','test_2');

コントローラーから渡された変数は{{}}で使用する。

変数をviewで使用する
<div>
  {{ $test_1 }}
</div>

@yield

指定した@sectionの内容を表示する。
つまり、@sectionの内容を埋め込みたい場所

app.blade.php
@yield('content')
index.blade.php
@section('content','これが表示されます'
@section('content')
 こんな書き方もあります
@endsection()

@sectionの使い方

基本
1. @yieldの場所に@section~@endsectionで記述を追加する
2. @yieldをなしでも、@section@showで表示可能。また,@sectionで上書きをしたり、@section~@parent~@endsection@showの内容を残しつつ、さらに記述を追加できる。

@sectionの書き方

//1 @endsection使わない場合
@section('title', 'アプリ名')

//1で変数を渡す場合
@section('title', $post->title)

//2 @endsectionを使う場合
@section('content')
<a></a>
@endsection

つまり、
yieldを指定して、endsectionを使って書くか、そうでないかのやり方が基本となる。

@includeは部分テンプレート

わかりやすいサイト

まとめ
//呼び出すだけ
@include('layouts.header')

//変数を渡して呼び出す
@include('layouts.header', ['テンプレート内の変数' => 渡す値])

headerを別ファイルにまとめて、土台となるapp.blade.phpに読み込ませる

layouts/app.blade.php
    <body>
        <div class="flex-center position-ref full-height">
          @include('layouts.header') # views/layouts.header.blade.phpを読み込む
        </div>
    </body>

変数を渡す場合

app.blade.php
<body>
  <h1>All the items:</h1>
  @foreach ($items as $foo)
    @include('partials.item-display', ['item' => $foo])
  @endforeach
</body>
item-dispay.blade.php
<div>
    Name: {{ $item->name }}<br>
    Description: {{{ $item->description }}}
</div>

extendsしたテンプレートへ挿入したいsectionはどこに書いても良い
extends宣言の前でも後でも良い
includeしたテンプレートへ挿入したいsectionは、includeするよりも先にsectionを書かないといけない
sectionの記述後にincludeしないといけない

エラーが起こるケース

複数行に改行している場合、エラーが発生
@include('my-partial-name', [
    'value1' => 'abc',
    'value2' => $some_var,
    'value3' => date('Y-m-d'),
])

参考リンク

views/layouts/app.blade.php
<html>
    <head>
        <title>アプリ名 - @yield('title')</title>
    </head>
    <body>
        @section('sidebar')
            ここがメインのサイドバー
        @show

        <div class="container">
            @yield('content')
        </div>
    </body>
</html>

layoutsを土台にして、index.blade.phpを作成する

views/tweets/index.blade.php
<!-- resources/views/child.blade.phpとして保存 -->

@extends('layouts.app') # layoutsフォルダの中にある、app.blade.phpを読み込む

@section('title', 'Page Title') # @yield('title')の中身をPage Titleにする

@section('sidebar')
    @parent

    <p>ここはメインのサイドバーに追加される</p>
@endsection

@section('content')
    <p>ここが本文のコンテンツ</p>
@endsection

実際に表示されるのは下記になる

ここがメインのサイドバー
ここはメインのサイドバーに追加される

ここが本文のコンテンツ

土台となるapp.blade.phpを作成

マニュアルはこちら

viewsの中にlayoutsフォルダを作成し、その中にapp.blade.phpを作成する

views/layouts/app.blade.php

{{}}XSS攻撃を防ぐ

メソッド

ループ処理

公式ドキュメント

@foreachは全部に適応 => エラーが出たりする
@forelseは空欄の時も設定できる => エラーが出ないようにカスタムしやすい

公式ドキュメント
@for ($i = 0; $i < 10; $i++)
    現在の値は {{ $i }}
@endfor

@foreach ($users as $user)
    <p>これは {{ $user->id }} ユーザーです</p>
@endforeach

@forelse ($users as $user)
    <li>{{ $user->name }}</li>
@empty
    <p>ユーザーなし</p>
@endforelse

@while (true)
    <p>無限ループ中</p>
@endwhile
brake処理

@continueで続行、@breakで終了

brakeで途中で終了させる
@foreach ($users as $user)
    @if ($user->type == 1)
        @continue
    @endif

    <li>{{ $user->name }}</li>

    @if ($user->number == 5)
        @break
    @endif
@endforeach

くは、ディレクティブに条件を記述して、一行で済ますこともできます。

ifをblakeに変更


@foreach ($users as $user)
    @continue($user->type == 1)

    <li>{{ $user->name }}</li>

    @break($user->number == 5)
@endforeach

ログイン判定

マニュアル
https://readouble.com/laravel/6.x/ja/blade.html

認証によって表示切り替え
@auth
    // ユーザーは認証済み
@else 
    // 
@endauth

@guest
    // ユーザーは認証されていない
@endguest

aタグにrouteのリンクを埋め込む

routeのnameを記述することで、リンク先のURLを簡単に指定できる

<a href={{ route('contacts.index') }}

フラッシュメッセージ

参考

補足情報

ページネーション

マニュアル

->paginate(表示件数)をつけるだけ

コントローラー
public function index()
    {
        #before
        $users = DB::table('users')->get();

        #after(getをpaginateに変更)
        $users = DB::table('users')->paginate(15);

        return view('user.index', ['users' => $users]);
    }

viewにページネーションを表示

viewに付与
{{ $users->links() }}

-> と =>の違い

->…オブジェクトのプロパティやメソッドを参照する場合に使う
=>…連想配列のキーと値を区切る場合に使う

=> ダブルアロー演算子
定義する際に利用する
配列のキーととバリューを定義する際に利用する。

キー => バリュー

rubyの場合
#シンボル型
[name: '田中', age: 19]

#ロケットハッシュ
[name => '田中', age => 19]

#laravelはシンボル型がない。

-> アロー演算子
表示する際に利用する
モデルのカラムを取り出したりする際に利用する。
左から右に取り出す

laravel
$user->name #名前を表示
$user->age #年齢を表示

テスト

わかりやすいサイト
参考にしようと思う記事
ログインのテスト
noteで参考になる記事
Laravelでテストコードを書くためのチュートリアル

テストファイルの作成

Featureテスト
実際の通信を伴う機能テスト

コマンド
php artisan make:test [テストケースクラス名]

php artisan make:test PostTest

Unitテスト
PHPクラス単位の単体テスト

コマンド
php artisan make:test [テストケースクラス名] --unit

php artisan make:test PostTest --unit

テストファイルの編集

注意: public function test~のようにtestが先頭にないと実行されない。

ExampleTest
<?php

namespace Tests\Feature;

use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class ExampleTest extends TestCase
{
    /**
     * @return void
     */
    public function testBasicTest()
    {
        $response = $this->get('/');
        $response->assertStatus(200);
    }
}

実例

TaskTestphp

<?php

namespace Tests\Unit;

// use PHPUnit\Framework\TestCase;
use Tests\TestCase;
use App\Models\Task;

class TaskTest extends TestCase
{
    /**
     * A basic unit test example.
     *
     * @return void
     * @test
     */
    public function testExample()
    {
        // $this->assertTrue(true);
        $response = $this->get('/tasks');
        $response->assertStatus(200);
    }

    public function testHttpIndex()
    {
        $response = $this->get('/tasks');
        $response->assertStatus(200);
    }

    public function testHttpCreate()
    {
        $response = $this->get('/tasks/create');
        $response->assertStatus(200);
    }

    public function testHttpShow()
    {
        $response = $this->get('/tasks/1');
        $response->assertStatus(200);
    }

    public function testHttpEdit()
    {
        $response = $this->get('/tasks/1/edit');
        $response->assertStatus(200);
    }

    public function testInsert_success()
    {
        $tasks = factory(Task::class, 3)->create();
        $count = count($tasks);
        $this->assertEquals(3, $count);
    }
}

実行すると
スクリーンショット 2020-11-29 18.29.22.png

実行方法

実行コマンド1(laravel7)
$ php artisan test

または

実行コマンド2
$ vendor/bin/phpunit

デバック

eval(\Psy\sh());

dd()

js

jsを使えるようにする

参考リンク

jsファイルを作成

resource/js/sample.js

#ここに記述をする

jsファイルを読み込みさせる

resource/js/app.js

require('./bootstrap');
require('./flashmessage');
require('./sample'); //requireで読み込みさせる
webpack.mix.js
const mix = require('laravel-mix');


mix.js([
        'resources/js/app.js',
        'resources/js/scroll.js',
        'resources/js/sample.js',
        'resources/js/comments.js',
    ], 'public/js')
    .sass('resources/sass/app.scss', 'public/css');

コマンド
npm run dev

個別に読み込ませるなど

css
<link href="{{ mix('css/app.css') }}" rel="stylesheet" type="text/css">

app.cssはscssなどをコンパイルしたもので、scssも問題なく利用できます。

js
@section('js')
<script src="{{ mix('js/app.js') }}"></script>
@show

非同期通信(AJAX)

非同期通信でデバックする方法

参考$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});

アクションを作成
public function getData()
{
    $comments = Comment::orderBy('created_at', 'desc')->get();
    $json = ["comments" => $comments];
    return response()->json($json);
}
json型でレスポンス
return response()->json($json);

json型について

ajaxを使って、jsonを取得する

ajaxを使えるようにするために、app.blade.phpのheadの部分でスクリプトを読み込む。

ajaxを使うスクリプト
<script src="{{ asset('js/app.js') }}" defer></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
ajaxのjsを作成
$.ajax({
    url: "result/ajax/",
    dataType: "json",
    success: data => {
      // 成功時の処理
    },
    error: () => {
      // エラー時の処理
    }
})

マニュアル

AJAXリクエストとバリデーション
この例ではアプリケーションにデータを送るために伝統的なフォームを使いました。しかし、多くのアプリケーションでAJAXリクエストが使用されています。AJAXリクエストにvalidateメソッドを使う場合、Laravelはリダイレクトレスポンスを生成しません。代わりにバリデーションエラーを全部含んだJSONレスポンスを生成します。このJSONレスポンスは422 HTTPステータスコードで送られます。

マニュアル

さらに追加でPOSTパラメーターとしてCSRFトークンを確認したい場合は、LaravelのVerifyCsrfTokenミドルウェアがX-CSRF-TOKENリクエストヘッダもチェックします。たとえば、HTML中のmetaタグにトークンを保存します。

<meta name="csrf-token" content="{{ csrf_token() }}">

metaタグを作成したら、jQueryのようなライブラリーで、全リクエストヘッダにトークンを追加できます。この手法によりAJAXベースのアプリケーションにシンプルで便利なCSRF保護を提供できます。



$.ajaxSetup({
    headers: {
        'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
    }
});

参考

jsonにリレーションのモデルを付与する

マニュアル
参考

パッケージ(ライブラリ)を入れる

参考になるサイト
参考になるサイト

追加方法

パッケージを後追いで追加する場合、

composer require {パッケージ名} で行います。

パッケージ名が hoge/huga の場合

$ ~/composer/composer.phar require hoge/huge

この場合は当該パッケージのみを入れ込み、またcomposer.jsonにも追記してくれます。

なお、hoge/hugeにあたるパッケージ名の一覧は
Packagistから探す。

バージョン指定してパッケージを後追いで追加したい

古いバージョンのモジュールを使う必要がある、というような場合にはバージョン指定で入れる。
composer require {パッケージ名}:{バージョン番号} で行います。
下記はhoge/hugaの2.6.30のバージョンを入れたい場合の例。

$ ~/composer/composer.phar require hoge/huge:2.6.30

バージョン番号もPackageistにあるのでそこを参考に。

# パッケージを追加
$ composer require [vendor/package]
# 実例
$ composer require goodby/csv
# バージョン指定してパッケージを追加
$ composer require goodby/csv:1.2.0

# 削除
$ composer remove [vendor/package]

# 「開発」で必要なものを追加
$ composer require --dev [vendor/package]

# 「開発」で必要なものを削除
$ composr remove --dev [vendor/package]

参考

21
29
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
21
29