20190411のlaravelに関する記事は6件です。

laravelテスト(データプロバイダを使って、テストコードの引数に与える値を変化させる)(Laravel学習メモ#7-2)

◆データプロバイダ

データプロバイダを使うと、同じテストコードに違うパラメータを与えることができる。

class ExampleTest extends TestCase
{
    /**
     * @dataProvider dataProvider
     * @param $int1
     * @param $int2
     */
    public function testSample($int1, $int2)
    {
        $this->assertSame($int1, $int2);
    }

    /**
     *
     */
    public function dataProvider()
    {
        return[
            [0,0],
            [0,1],
            [1,1]
        ];
    }
}

データプロバイダは、配列もしくは、iterotorを実装したループ可能なインスタンスを返すようにして、使うメソッドのコメントでdataProviderアノテーションを指定する必要がある
testSampleメソッドの引数が2つなので、dataProviderメソッド(publicで指定する必要あり)は2つの値を持つ配列を用意する。
今回は、3つ用意したので、3回テストが実行される。

PHPUnit 7.5.8 by Sebastian Bergmann and contributors.

.F.                                                                 3 / 3 (100%)

Time: 980 ms, Memory: 14.00 MB

There was 1 failure:

1) Tests\Unit\ExampleTest::testSample with data set #1 (0, 1)
Failed asserting that 1 is identical to 0.

/var/www/tests/Unit/ExampleTest.php:17

FAILURES!
Tests: 3, Assertions: 3, Failures: 1.

テストが失敗したときに与えた組み合わせの値が表示されるのもすごくありがたい。

メッセージをつける
public function dataProvider()
{
    return[
        '0と0です' => [0,0],
        '0と1です' => [0,1],
        '1と1です' => [1,1]
    ];
}
PHPUnit 7.5.8 by Sebastian Bergmann and contributors.

.F.                                                                 3 / 3 (100%)

Time: 990 ms, Memory: 14.00 MB

There was 1 failure:

1) Tests\Unit\ExampleTest::testSample with data set "0と1です" (0, 1)
Failed asserting that 1 is identical to 0.

/var/www/tests/Unit/ExampleTest.php:17

FAILURES!
Tests: 3, Assertions: 3, Failures: 1.

次から書くときつかお

[参考にさせていただいた記事]
https://qiita.com/Hiraku/items/5c49987f4e9e167dad86

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

Laravelでテーブルと初期値を作成する

はじめに

Laravelのマイグレーションファイルとシーダーファイルを使って、テーブルとその初期値を作成します。

準備

データベースの作成

まず、データベースを作成します。
プロジェクトで使用する「データベース」「ユーザー」「パスワード」を作成しておきます。
各自の環境によるので、割愛します。

データベース接続の設定

Laravelプロジェクト直下にある「.env」ファイルを以下のように修正します。

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE="データベース名"
DB_USERNAME="ユーザー名"
DB_PASSWORD="ユーザーパスワード"

mysql以外を使用する場合は、DB_CONNECTION等も修正します。
準備は完了です。

テーブルの作成

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

Larabelプロジェクトの直下に移動後、コンソールで以下のコマンドを実行します。
今回はテーブル名を"items"とします。

php artisan make:migration create_items_table

以下の表示が出れば成功です。

Created Migration: yyyy_MM_dd_HHmmss_create_items_table

(yyyy_MM_dd_HHmmssは作成時の日時が入ります。)

マイグレーションファイルの修正

作成したマイグレーションファイルは、Laravelプロジェクト>database>migrations下に作られています。
初期状態で以下の内容が書かれています。
upはマイグレーションを実行する際に実行され、downはマイグレーションを元に戻す際に実行されます。

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

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

upの中に列の定義を記述します。
$table->"型名"("列名")の形です。

            $table->bigIncrements('id');
            $table->string('name'); // 追加
            $table->timestamps();

マイグレーションの実行

Larabelプロジェクトの直下に移動後、コンソールで以下のコマンドを実行します。

php artisan migrate

以下の表示が出れば成功です。

Migrating: yyyy_MM_dd_HHmmss_create_items_table
Migrated:  yyyy_MM_dd_HHmmss_create_items_table

環境によっては、「SQLSTATE[42000]: Syntax error or access violation」が出ます。
いくつか方法があるようですが、私は以下の対策をしました。

Laravelプロジェクト>app>Providers>AppServiceProvider.phpファイルのboot()内に、以下の記述を追加します。

    public function boot()
    {
        Schema::defaultStringLength(191);
    }

モデルの作成

Larabelプロジェクトの直下に移動後、コンソールで以下のコマンドを実行します。

php artisan make:model Item

以下の表示が出れば成功です。

Model created successfully.

初期値の作成

シーダーファイルの作成

Larabelプロジェクトの直下に移動後、コンソールで以下のコマンドを実行します。

php artisan make:seeder ItemsTableSeeder

以下の表示が出れば成功です。

Seeder created successfully.

シーダーファイルの修正

作成したマイグレーションファイルは、Laravelプロジェクト>database>seeds下に作られています。
初期状態で以下の内容が書かれています。

class ItemsTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        //
    }
}

runの中に初期値の作成を記述します。
流れは、
「先ほど作成したモデルをnewする→値を設定→save()で登録」
です。
複数件作りたい場合は、for文などで記述します。

        for($i = 1; $i <= 5; $i++)
        {
            $item = new Item();
            $item->name = '名前' . $i;
            $item->save();
        }

シーダーの実行

Larabelプロジェクトの直下に移動後、コンソールで以下のコマンドを実行します。

php artisan db:seed --class=ItemsTableSeeder

以下の表示が出れば成功です。

Database seeding completed successfully.

確認すると、きちんと追加されていました。

+----+-------+---------------------+---------------------+
| id | name  | created_at          | updated_at          |
+----+-------+---------------------+---------------------+
|  1 | 名前1 | 2019-04-11 21:13:35 | 2019-04-11 21:13:35 |
|  2 | 名前2 | 2019-04-11 21:13:35 | 2019-04-11 21:13:35 |
|  3 | 名前3 | 2019-04-11 21:13:35 | 2019-04-11 21:13:35 |
|  4 | 名前4 | 2019-04-11 21:13:35 | 2019-04-11 21:13:35 |
|  5 | 名前5 | 2019-04-11 21:13:35 | 2019-04-11 21:13:35 |
+----+-------+---------------------+---------------------+
5 rows in set (0.00 sec)

コマンドまとめ

マイグレーションファイル作成
※テーブル名は「小文字始まり、複数形」

php artisan make:migration create_"テーブル名"_table

マイグレーション実行

php artisan migrate

モデル作成
※モデル名は「大文字始まり、単数形」

php artisan make:model "モデル名"

シーダーファイル作成

php artisan make:seeder "モデル名の複数形"TableSeeder

シーダーの実行

php artisan db:seed --class="シーダー名"
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Laravelのクエリビルダを使い回す際の注意

はじめに

  • Laravel初心者向け
  • 自分がハマったので他の人がハマらないように残す

該当ソース

        $company_where = Company::where(['is_valid' => '1']);
        $company1 = $company_where->where(['id' => '1'])->toSql();
        var_dump($company1);
        // "select * from `companies` where (`is_valid` = ?) and (`id` = ?)"
        $company2 = $company_where->where(['id' => '2'])->toSql();
        var_dump($company2);
        // "select * from `companies` where (`is_valid` = ?) and (`id` = ?) and (`id` = ?)"

やりたいことはis_validが1の企業(有効な企業)の中でid=1のもの、2のものを取得したい
is_validの条件は共通なので変数に持ち、それを使いまわそうと思って書いたコードなのですが見事にハマりました
id=1は無事に取れるが、id=2が何故かとれない…レコードはあるしis_valid=1なのに何故…

解説

もうソースにコメントで書いてありますがtoSqlで発行されるクエリに注目です

-- 1つ目
select * from `companies` where (`is_valid` = ?) and (`id` = ?)
-- 2つめ
select * from `companies` where (`is_valid` = ?) and (`id` = ?) and (`id` = ?)

2番目のクエリにidの検索条件がANDで2つついているのが分かるかと思います
1つ目のクエリのwhereでid=1の検索条件がつき、2つ目のクエリで上書きされるかと思いきや同じカラムでもAND検索で追加される仕様のようでした
(まぁメソッドチェーンでAND検索になるんだから当然っちゃ当然なんですが。。。)

解決策

大人しくインスタンスを分けましょう

        $company_where1 = Company::where(['is_valid' => '1']);
        $company1 = $company_where1->where(['id' => '1'])->toSql();
        var_dump($company1);
        // "select * from `companies` where (`is_valid` = ?) and (`id` = ?)"
        $company_where2 = Company::where(['is_valid' => '1']);
        $company2 = $company_where2->where(['id' => '2'])->toSql();
        var_dump($company2);
        // "select * from `companies` where (`is_valid` = ?) and (`id` = ?)"

もしくはクエリを分けなくても良い方法を考えましょう

        $companies = Company::where(['is_valid' => '1'])
            ->whereIn('id', ['1', '2'])
            ->toSql();
        var_dump($companies);
        // "select * from `companies` where (`is_valid` = ?) and `id` in (?, ?)"

おわりに

自分と同じ状況でハマっている人が解決したなら良かったです

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

DjangoのtemplateとLaravelのbladeの構文をちょっと比較してみた

まとめ

  • 両者非常に似通っていて、同じ感覚で使用できる

  • Laravelでは親の@yieldに子の@sectionが展開されるが、Djangoでは親子ともにblockで表現する

  • Laravelでは、@extendslayouts/app.blade.phpを使用する際に、layouts.appと指定する(layouts/appではない)のが少し戸惑った

Djangoの場合

親のテンプレート

templates/base.html
<!DOCTYPE html>
<html>
<head>
  ...
</head>
<body>
  <header>
    ...
  </header>
  <main>
    {% block content %}
    {% endblock %}
  </main>
  <footer>
    ...
  </footer>
</body>

子のテンプレート

templates/hoge/fuga.html
{% extends 'base.html' %}

{% block content %}
<div>
  {% if items %}
    <ul>
       {% for item in items %}
         <li>{{ item }}</li>
       {% endfor %}
    </ul>
  {% endif %}
</div>
{% endblock %}

Laravelの場合

親のテンプレート

resources/views/layouts/app.blade.php
<!DOCTYPE html>
<html>
<head>
  ...
</head>
<body>
  <header>
    ...
  </header>
  <main>
    @yield('content')
  </main>
  <footer>
    ...
  </footer>
</body>

子のテンプレート

resources/views/hoge.blade.php
@extends('layouts.app')

@section('content')
<div>
  @if (count($items)) > 0)
    <ul>
       @foreach( $items->all() as $item)
         <li>{{ $item }}</li>
       @endforeach
    </ul>
  @endif
</div>
@endsection
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Laravelでテーブルのカラムを削除する方法

Laravelでテーブルのカラムを削除する

  1. migrationファイルを作る
  2. 中身を記述する
  3. 実行!

migrationファイルを作る

`hoge' には該当のテーブル名を入れてください

migrationファイル作成
php artisan make:migration drop_column_hoges_column --table=hoges

テーブルカラムの削除処理を記述

upの方に削除処理を記述し、downの方にはカラム追加処理を記述しましょう。

以下の書き方で piyo カラムを削除することができます

<?php

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

class DropColumnHogesTable extends Migration
{
  /**
   * Run the migrations.
   *
   * @return void
   */
  public function up()
  {
    Schema::table('hoges', function (Blueprint $table) {
      $table->dropColumn('piyo');
    });
  }

  /**
   * Reverse the migrations.
   *
   * @return void
   */
  public function down()
  {
    Schema::table('hoges', function (Blueprint $table) {
      $table->boolean('piyo')->default(false);
    });
  }
}

テーブルのカラム削除をLaravelで実行する

実行時はこちら

php artisan migrate

そしてrollbackも実行しておきましょう。

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

Laravelでcronを使ったタスクスケジュール

* * * * * php /path-to-your-project/artisan schedule:run >> /dev/null 2>&1

これだけcron登録、あとはLaravelで

php artisan make:controller TaskController
php artisan make:command SendMailCommand

そしてapp/Console/Kernel.phpを修正
の流れでタスクを登録できるという話だったのだが、cron登録で詰まったので投稿。

正しくは

* * * * * /usr/local/bin/php /path-to-your-project/artisan schedule:run >> /var/log/task.log 2>&1

cronはコマンドを全てフルパスで入力する必要がある。
また、dev/nullの代わりにログ出力先を指定してあげればcronのログを吐くようになる。

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