20200929のlaravelに関する記事は7件です。

laravelでターミナルからログを出す(メモ)

tail -f storage/logs/"見たいファイルの名前"

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Laravelルーティング

Laravelにおけるルーティングを説明していきます。

ルーティングとは

ブラウザから任意のURLアクセスがあった場合、どのController処理を動かすのかを定義するところになります。記述する場所はroutes/web.phpになります。またHTTPメソッド(GET,POST,PUT等)も定義できます。下記のイラストの①の部分にあたります。
imager.png

ルーティングの書き方

記載する場所はroutes/web.phpになります。
例) ブログ一覧を表示したい

routes/web.php
Route::get('blogs','BlogContoller@showlist');

左から順に説明します。
1. Laravel既存機能のRouteファサードを使う(Route)
2. HTTPメソッドの指定(get)
3. 任意のURLを指定(blogs)
4. 作ったControllerを指定(BlogContoller)
5. Controllerのメソッドを指定(showlist)

名前付きルート

作成したRouteに名前をつける事ができます。これにより特定のルートへのURLを生成したり、リダイレクトしたりする場合に便利です。ルート定義にnameメソッドをチェーンする事で名前がつけられます。

routes/web.php
Route::get('/','BlogContoller@showlist')->name('blogs');

生成+リダイレクト

ルートに一度名前を付ければ、その名前をグローバルなroute関数で使用すればURLを生成したり、リダイレクトしたりできます。

//URLの生成
$url = route('blogs');
//リダイレクトの生成
return redirect()->route('profile');

URLを一括で変更できる

viewで

{{ url('/users/1/profile')}}

上記のように書いてしまうと、URLを変更する際にviewの中から同じ箇所を探さないといけなくなってしまいますが、

{{ route('user.profile',['id' => 1])}}

としていれば、routes/web.phpのみを変更すればよくなります。

resource

resourceはリソースコントローラーと呼ばれ、一般的なCRUD(投稿、一覧、更新、削除、詳細)操作を予めLaravel側で用意してくれるものです。web.phpでHTTP動詞をRoute::resourceとする事で以下のメソッドを定義した扱いとなります。また、name()も勝手に付与してくれます。
1. index(一覧)
2. show(詳細)
3. create(作成画面)
4. store(作成処理)
5. edit(編集画面)
6. update(編集処理)
7. destroy(削除処理)

これにより、かなりのコード短縮化が図れます。
一つずつ

web.php
Route::get('admin/post', 'Admin/PostController@index')->name('admin.post.index');
    Route::get('admin/post/show/{id}', 'Admin/PostController@show')->name('admin.post.show');
    Route::get('admin/post/create', 'Admin/PostController@create')->name('admin.post.create');
    Route::post('admin/post/store', 'Admin/PostController@store')->name('admin.post.store');
    Route::get('admin/post/edit/{id}', 'Admin/PostController@edit')->name('admin.post.edit');
    Route::post('admin/post/update/{id}', 'Admin/PostController@update')->name('admin.post.update');
    Route::post('admin/post/destroy/{id}', 'Admin/PostController@destroy')->name('admin.post.destroy');

resource版

Route::resourcre('post','PostController');

また、以下のartisanコマンドで対応するコントローラとメソッドを自動生成してくれます。

$ php artisan make:controller PhotoController --resource
PhotoController
//コマンド入力で自動的に作成される
namespace App\Http\Controllers;
class PhotoController extends Controller
{
    public function index()
    {
        //
    }

    public function create()
    {
        //
    }

    public function store(Request $request)
    {
        //
    }

    public function show($id)
    {
        //
    }

    public function edit($id)
    {
        //
    }

    public function update(Request $request, $id)
    {
        //
    }

    public function destroy($id)
    {
        //
    }
}

onlyオプション/exeptオプション

これにより、resource使った時のルーティングを制限する事ができるので、余計なルーティングを生成しないで済みます。

routes/web.php
//edit,updateのルーティングを削除

//only
Route::resource('hoge', 'HogeController', ['only' => ['index','create','show','store','destroy']]);
//except
Route::resource('hoge', 'HogeController',[except => ['edit','update']]);

resource懸念点

実務でresourceを使ってしまうと、使わないルートまで定義されてしまうので、「個別で書いた方がいい」、「only,exceptオプションを使う」という意見があるらしいです。使う用途によって使い分けた方が良さそうです。

終わりに

参考サイト
https://qiita.com/sympe/items/9297f41d5f7a9d91aa11
https://qiita.com/namizatork/items/78487c2504b7ad4faf27

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Laravel Passportでgrant_typeを制限する

https://qiita.com/h1na/items/25a08122418df782d2b9
ここにほとんど書いてある

Laravel公式に追加しろって書いてあるPassport::routes(); ←これ

public function boot()
    {
        $this->registerPolicies();

        Passport::routes();
    }

たどってPassport.phpをみてみると、 デフォルトのコールバックが$router->all();

public static function routes($callback = null, array $options = [])
    {
        $callback = $callback ?: function ($router) {
            $router->all();
        };
    }

all()って何?って思ったら\Laravel\Passport\RouteRegisterに書いてあった

public function all()
    {
        $this->forAuthorization();
        $this->forAccessTokens();
        $this->forTransientTokens();
        $this->forClients();
        $this->forPersonalAccessTokens();
    }

じゃあ例えば、forAuthorizationforAccessTokensだけ使いたい!ってなったとき

        Passport::routes(function (RouteRegistrar $router) {
            $router->forAuthorization();
            $router->forAccessTokens();
        });

こうすればいい

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[Laravel8] Factoryの使い方メモ

Laravel8でテストデータを入れたい時の、Factoryの使い方メモです。
環境:XAMPP for Windows, Laravel Framework 8.6.0

☞ 今回のケース ☜
・ 例えば、Twitterのクローンアプリを作っていて、ツイートを管理するテーブルにテストデータを入れたい時。
マイグレーションファイルはこのような感じ。↓↓ データを入れたいのは、'user_id'と、'body'の二つだけ。

database\migrations\2020_09_28_045814_create_tweets_table.php
    public function up()
    {
        Schema::create('tweets', function (Blueprint $table) {
            $table->id();
            $table->foreignId('user_id');
            $table->string('body');
            $table->timestamps();
        });
    }

手順1.ターミナルで以下コマンドを打って、TweetFactory.php を作る。
・database\factories\TweetFactory.php にファイルができます!

php artisan make:factory TweetFactory --model=Tweet

手順2.Laravel8になってから、globalなfactory()関数は削除されました。その為、モデルのFactoryクラスを使います。
該当するモデルファイルに、『Illuminate\Database\Eloquent\Factories\HasFactory』がインポートされているかを確認すること。

\app\Models\Tweet.php
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory; // ←ここ確認。
use Illuminate\Database\Eloquent\Model;

class Tweet extends Model
{
    use HasFactory;
}

手順3:作成したTweetFactory.phpを編集する。
・連携するモデルがインポートされているかを確認して、return[]部分を追記します。

database\factories\TweetFactory.php
<?php

namespace Database\Factories;

use App\Models\Tweet; //←モデルがインポートされているかを確認!
use App\Models\User; //←モデルがインポートされているかを確認!
use Illuminate\Database\Eloquent\Factories\Factory;

class TweetFactory extends Factory
{
    /**
     * The name of the factory's corresponding model.
     *
     * @var string
     */
    protected $model = Tweet::class;

    /**
     * Define the model's default state.
     *
     * @return array
     */
    public function definition()
    {
        return [
            'user_id' => User::factory(), //←ここ追記
            'body' => $this->faker->sentence //←ここ追記
        ];
    }
}

手順4. DatabaseSeeder.phpに追記する。

database\seeders\DatabaseSeeder.php
<?php

namespace Database\Seeders;

use Illuminate\Database\Seeder;

class DatabaseSeeder extends Seeder
{
    /**
     * Seed the application's database.
     *
     * @return void
     */
    public function run()
    {
        // \App\Models\User::factory(10)->create();
        \App\Models\Tweet::factory(10)->create(); //←ここ追記
    }
}

手順5.seedを実行する。
ターミナルで以下コマンドを実行します。

php artisan db:seed

以上で該当のテーブルにテストデータが入ります。
usersテーブルにもデータが入り。。
image.png

tweetsテーブルにもデータが入ってる!
image.png

テストデータを日本語にしたい場合は、config/app.phpの'faker_locale'を以下のように修正します。

config/app.php
'faker_locale' => 'ja_JP', 

以上です。

*因みに、上記の手順はteamsオプションを追加していない場合です。teamsオプションを有効にしてJetstreamをインストールしている場合は、以下の参考サイトさんで分かりやすく説明頂いていたので、ご参考に!

参考サイト:
https://blog.capilano-fw.com/?p=7827#Factory

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[Laravel8]Factoryの使い方メモ

Laravel8でテストデータを入れたい時の、Factoryの使い方メモです。
環境:XAMPP for Windows, Laravel Framework 8.6.0

☞ 今回のケース ☜
・ 例えば、Twitterのクローンアプリを作っていて、ツイートを管理するテーブルにテストデータを入れたい時。
マイグレーションファイルはこのような感じ。↓↓ データを入れたいのは、'user_id'と、'body'の二つだけ。

database\migrations\2020_09_28_045814_create_tweets_table.php
    public function up()
    {
        Schema::create('tweets', function (Blueprint $table) {
            $table->id();
            $table->foreignId('user_id');
            $table->string('body');
            $table->timestamps();
        });
    }

手順1.ターミナルで以下コマンドを打って、TweetFactory.php を作る。
・database\factories\TweetFactory.php にファイルができます!

php artisan make:factory TweetFactory --model=Tweet

手順2.Laravel8になってから、globalなfactory()関数は削除されました。その為、モデルのFactoryクラスを使います。
該当するモデルファイルに、『Illuminate\Database\Eloquent\Factories\HasFactory』がインポートされているかを確認すること。

\app\Models\Tweet.php
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory; // ←ここ確認。
use Illuminate\Database\Eloquent\Model;

class Tweet extends Model
{
    use HasFactory;
}

手順3:作成したTweetFactory.phpを編集する。
・連携するモデルがインポートされているかを確認して、return[]部分を追記します。

database\factories\TweetFactory.php
<?php

namespace Database\Factories;

use App\Models\Tweet; //←モデルがインポートされているかを確認!
use App\Models\User; //←モデルがインポートされているかを確認!
use Illuminate\Database\Eloquent\Factories\Factory;

class TweetFactory extends Factory
{
    /**
     * The name of the factory's corresponding model.
     *
     * @var string
     */
    protected $model = Tweet::class;

    /**
     * Define the model's default state.
     *
     * @return array
     */
    public function definition()
    {
        return [
            'user_id' => User::factory(), //←ここ追記
            'body' => $this->faker->sentence //←ここ追記
        ];
    }
}

手順4. DatabaseSeeder.phpに追記する。

database\seeders\DatabaseSeeder.php
<?php

namespace Database\Seeders;

use Illuminate\Database\Seeder;

class DatabaseSeeder extends Seeder
{
    /**
     * Seed the application's database.
     *
     * @return void
     */
    public function run()
    {
        // \App\Models\User::factory(10)->create();
        \App\Models\Tweet::factory(10)->create(); //←ここ追記
    }
}

手順5.seedを実行する。
ターミナルで以下コマンドを実行します。

php artisan db:seed

以上で該当のテーブルにテストデータが入ります。
usersテーブルにもデータが入り。。
image.png

tweetsテーブルにもデータが入ってる!
image.png

テストデータを日本語にしたい場合は、config/app.phpの'faker_locale'を以下のように修正します。

config/app.php
'faker_locale' => 'ja_JP', 

以上です。

*因みに、上記の手順はteamsオプションを追加していない場合です。teamsオプションを有効にしてJetstreamをインストールしている場合は、以下の参考サイトさんで分かりやすく説明頂いていたので、ご参考に!

参考サイト:
https://blog.capilano-fw.com/?p=7827#Factory

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Laravelモデル

今回はmvcモデルのM(モデル)の作成をしていきます。

Model

モデルとはビジネスロジックを書く場所になります。また、データを処理したり、データをDBに保存するところです。逆に、DBから情報を取り出して、Controllerに送ったりしてくれます。
image
そして、Laravelでモデルを扱うにはEloquent ORM を使っていきます。

Eloquent ORM

Laravelで提供されているデータ操作のための機能で、「モデル」と「DB」を対応付けてくれます。ORMとは「Object Relational Mapping」の略称で、プログラミング技法のことです。これにより、DBから取得してきた情報をオブジェクトとして扱う事ができます。

Eloquentモデルの作り方

$ php artisan make:model モデル名

* モデル名はテーブルの単数形にする必要がある
このコマンドを打つとファイルが生成されるので、その中にmodelの定義などを書いていきます。また、他のテーブルとの紐付けもこのファイルで操作できます。コマンドを打ち、ファイルが作成されたら、ファイルに記述を加えていきます。

<?php

namespace App\Models\Modols;

// use Illuminate\Database\Eloquent\Factories\HasFactory;//テストで使うらしいです。
use Illuminate\Database\Eloquent\Model;

class Blog extends Model//上のモデルを継承してBlogというクラスを作っている
{
    // use HasFactory;//テストで使うらしいです。
    //テーブル名
    protected $table = 'blogs';//使いたいテーブル名を指定

    //可変項目
    protected $fillable = 
    [
        'title',
        'content'
    ];
}

$fillableとguarded

上記で可変項目として、'title','content'と書いてあると思いますが、ここについて説明していきます。
isertやcreateメソッドでテーブルのカラムに値を挿入する際、予期せぬ代入が起こる事を防ぐために、モデルへ、$fillable or $guardedを設定する必要があります。

予期せぬ代入とは

複数代入による予期せぬ代入とは、製作者が意図していない代入のことです。ユーザーから変えて欲しくない値(id,passwordなどの管理者権限を管理するカラム)を自由に変えられてしまっては困ります。そこで入力によって変動する値を安全に管理するために、$fillable or $guardedで値を管理します。

$fillable

$fillableとはホワイトリストと言い、複数代入時に代入を許可する属性を配列で設定します。解釈があってるか分かりませんが、変更可能な値を保存する時に使います。

protected $fillable = ['name','age','update_at'];

$guraded

$guardedは$fillableとは逆にブラックリストと言い、複数代入時に代入を許可しない属性と配列で設定します。変更して欲しくない値を保存する際に使います。両者の属性は併せて使うことはできません。

protected $guarded = ['id'];

他の生成メソッド

他にも属性の複数代入可能なメソッドが2つあります。firstOrCreatefirstOrNewです。

firstOrCreate

指定されたカラム/値ペアでデータベースレコードを見つけようとします。モデルがデータベースで見つからない場合には指定された属性でレコードが挿入されます。

$flight = App\Flight::firstOrCreate(['name'] => 'Flight 10');//属性のフライトを取得するか、存在しなければ作成

firstOrNew

指定されたデータベースのレコードを見つけようとします。モデルが見つからない場合は、新しいモデルインスタンスが返されます。こちらが返すモデルはデータベースに保存されません。保存するにはsaveメソッドが必要になります。

$flight = App\Flight::firstOrNew(['name'] => 'Flight 10');//属性のフライトか、存在しなければ、新しいインスタンスを取得する

モデル削除

モデルを削除する際には、モデルに対して、deleteメソッドを呼び出します。

$flight = App\Flight::find(1);
$flight =->delete();

上記ではdeleteメソッドを呼び出す前にデータベースからモデルを取得しています。しかしモデルの主キーが分かっているのならdestroyメソッドを使えます。これによりモデルを取得せずに削除できます。

App\Flight::destroy(1);
App\Flight::destroy([1,2,3]);

終わりに

基本的なモデルの説明でした。

参考サイト
https://snome.jp/framework/mvc-model/
https://qiita.com/kk_take/items/3e0639ed605f74c34619
https://udemy.benesse.co.jp/development/web/laravel-model.html

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Laravel テストコードを書いてみよう

目的

  • Laravelのフューチャーテストコードの書き方をまとめる

実施環境

  • ハードウェア環境
項目 情報
OS macOS Catalina(10.15.5)
ハードウェア MacBook Pro (13-inch, 2020, Four Thunderbolt 3 ports)
プロセッサ 2 GHz クアッドコアIntel Core i5
メモリ 32 GB 3733 MHz LPDDR4
グラフィックス Intel Iris Plus Graphics 1536 MB
  • ソフトウェア環境
項目 情報 備考
PHP バージョン 7.4.8 Homwbrewを用いて導入
Laravel バージョン 8.6.0 commposerを用いてこちらの方法で導入→Mac Laravelの環境構築を行う
MySQLバージョン 8.0.19 for osx10.13 on x86_64 Homwbrewを用いてこちらの方法で導入→Mac HomebrewでMySQLをインストールする

前提条件

  • 実施環境と同じ、もしくは準ずる環境が構築されていること。

前提情報

  • Laravelのテストはフューチャーテストとユニットテストが存在しこの記事ではフューチャーテストの方法を紹介する。
  • MacのローカルにLaravelアプリを作成し$ php artisan serveコマンドを用いてローカルサーバを起動して確認するものする。
  • 「特定の文字がビューに表示されているか」と「Httpステータスコードの200が帰ってくるか」を確認する。

概要

  1. アプリの作成
  2. ルート情報の記載
  3. コントローラーファイルの作成と記載
  4. ビューファイルの作成と記載
  5. テストコードの作成と記載
  6. テストの実行

詳細

  1. アプリの作成

    1. 任意のディレクトリで下記コマンドを実行してLaravelアプリを作成する。

      $ laravel new feature_test
      
    2. 先のコマンドで作成されたfeature_testディレクトリに移動する。

  2. ルート情報の記載

    1. feature_testディレクトリで下記コマンドを実行してルーティングファイルを開く。

      $ vi routes/web.php
      
    2. 下記のルーティング情報を追記する。

      feature_test/routes/web.php
      Route::get('/hello', 'App\Http\Controllers\HelloController@index');
      
    3. 追記後のルーティングファイルの内容を下記に記載する。

      feature_test/routes.web.php
      <?php
      
      use Illuminate\Support\Facades\Route;
      
      /*
      |--------------------------------------------------------------------------
      | Web Routes
      |--------------------------------------------------------------------------
      |
      | Here is where you can register web routes for your application. These
      | routes are loaded by the RouteServiceProvider within a group which
      | contains the "web" middleware group. Now create something great!
      |
      */
      
      Route::get('/', function () {
          return view('welcome');
      });
      // 下記を追記する。
      Route::get('/hello', 'App\Http\Controllers\HelloController@index');
      
  3. コントローラーファイルの作成と記載

    1. feature_testディレクトリで下記コマンドを実行してコントローラファイルを作成する。

      $ php artisan make:controller HelloController
      
    2. feature_testディレクトリで下記コマンドを実行して先に作成したコントローラファイルを開く。

      $ vi app/Http/Controllers/HelloController.php
      
    3. 開いたコントローラファイルに下記のアクションを追記する。

      feature_test/app/Http/Controllers/HelloController.php
          public function index()
      {
          return view('hello/index');
      }
      
    4. 追記後のコントローラファイルの内容を下記に記載する。

      feature_test/test/Http/Controllers/HelloController.php
      <?php
      
      namespace App\Http\Controllers;
      
      use Illuminate\Http\Request;
      
      class HelloController extends Controller
      {
          public function index()
          {
              return view('hello/index');
          }
      }
      
  4. ビューファイルの作成と記載

    1. feature_testディレクトリで下記コマンドを実行してビューファイルを格納するディレクトリを作成する。

      $ mkdir resources/views/hello
      
    2. feature_testディレクトリで下記コマンドを実行してビューファイルを作成する。

      $ vi resources/views/hello/index.blade.php
      
    3. 開いたファイルに下記の内容を記載する。

      resources/views/hello/index.blade.php
      <h1>hello japan!</h1>
      
    4. feature_testディレクトリで下記コマンドを実行してローカルサーバを起動する。

      $ php artisan serve
      
    5. 下記にアクセスして「Hello japan!」の文字が表示されていることを確認する。

  5. テストコードの作成と記載

    1. feature_testディレクトリで下記コマンドを実行してテストコード用のファイルを作成する。

      $ php artisan make:test HelloIndexPageTest
      
    2. feature_testディレクトリで下記コマンドを実行して先に作成したテストコードファイルを開く。

      $ vi tests/Feature/HelloIndexPageTest.php
      
    3. 開いたテストコードファイルを下記の様に追記・修正をする。

      feature_test/tests/Feature/HelloIndexPageTest.php
      <?php
      
      namespace Tests\Feature;
      
      use Illuminate\Foundation\Testing\RefreshDatabase;
      use Illuminate\Foundation\Testing\WithFaker;
      use Tests\TestCase;
      
      class HelloIndexPageTest extends TestCase
      {
          /**
           * A basic feature test example.
           *
           * @return void
           */
          public function testStatusCode()
          {
              $response = $this->get('/hello');
      
              $response->assertStatus(200);
          }
      
          public function testBody()
          {
              $response = $this->get('/hello');
      
              $response->assertSeeText('hello japan!');
          }
      }
      
  6. テストの実行

    1. feature_testディレクトリで下記コマンドを実行してテストを実行する。

      $ vendor/bin/phpunit tests/Feature/HelloIndexPageTest.php
      
    2. 下記の様に出力されればテストは完了であり、当該ページはテスト条件を満たしている。

      OK (2 tests, 2 assertions)
      

参考文献

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む