Laravel8のFactoryを使ってテストデータを作成する方法

Laravel8のFactoryを使ってテストデータを作成する方法を解説します。
Laravel8になって、Factoryの書き方が少し変わったので、そちらの紹介をしていきます。

細かい解説については、公式サイトの方で紹介されております。
是非確認してみてください。

データベースのテスト Laravel8

しかし、公式サイトは、Laravelへの(Factory・Seederへの)理解が十分であれば、サラッと理解できるかもしれません。
経験がまだ浅い方(私のように)には少しとっつき辛い部分もあると思います。

ざっくりとした、概要から解説していきたいと思います。

LaravelのFactoryとは何か

まず、Factoryとは何か。簡単に言うと、Laravelのデータベーステストにおいて、簡単に、そして大量にデータベースにデータを登録するための機能です。
Seederという機能はご存知でしょうか。
こちらも、データベースにテストデータを登録していく機能です。

Seederを単体で使う場合には、データを1つづつ自前で 記述していく必要があります。そこで、Factoryという機能をSeederと一緒に使うことによって、自前で記述しないで、Factoryに一定の指示をした通りに、ランダムなデータを大量に作成してくれます。

あまり理解できない人がいるでしょうか。

Seeder:登録したいデータを、そのまんま記述します。

user_id = 1 / name="taro" / email="taro@gmail.com"
user_id = 2 / name="jiro" / email="jiro@gmail.com"
user_id = 3 / name="saburo" / email="saburo@gmail.com"

Factory :必要な要素だけ指定して、ランダムにデータを作成

user_id = int型 / name = string型 / email = string型@gmail.com
3件データを作成

みたいな感じで、指定するとランダムでデータを作成してくれます。

Laravel8でのFactoryを活用したテストデータの作成方法を解説

まずは、ざっくりとした流れを解説していきます。

1; Factoryでデータ定義を作る
2:seederでファクトリーを設定
3: DatabaseSeeder で seeder callする
4: php artisan db:seed

1:Factoryでデータ定義を作る

Factoryですることは、作成するデータの定義を設定することです。
どんなカラムが存在しており、カラムのデータ型は何か、どんな値を設定したいのか(例えば、10桁のランダム文字列 など)などを指定していきます。

Factoryを設定するためには、Factoryファイルを作成する必要があります。
コマンドでファイルを作成していきます。

ChatMessageに利用するデータをFactoryを活用して作成していきます。
Modelは ChatMessage です。

 php artisan make:factory ChatMessageFactory 

これで、ChatMessageFactory のファイルが作成されます。

Laravel8での変更点としては、まずはこのデFactoryファイルでのデータ定義部分が変更されています。

public function definition(){}の中にデータの定義を記載していきます。

public function definition()
{
    return [
        'chat_room_id' => $this->faker->numberBetween($min = 1, $max = 10),
        'user_id' => $this->faker->randomDigit,
        'message' => Str::random(10),
        'created_at' => date('Y-m-d H:i:s'),
        'updated_at' => date('Y-m-d H:i:s'),
    ];
} 

chat_room_id、user_id、message、created_at、updated_atはデータベースのカラムの名称です。

これらのカラムに対して、fakerというものを使って、データの定義を決定していきます。

$this->faker->numberBetween($min = 1, $max = 10),

最低数が1、最大数が10の整数値 を作ってという指示です。

$this->faker->randomDigit,

ランダムの整数値 を作ってという指示です。

'message' => Str::random(10),

ランダムの10桁の文字列を作って、という指示です。

date('Y-m-d H:i:s'),

時刻表示の定義に合わせて、時間のデータを作って、という指示です。

こんな感じで、Factoryファイルでは、データの定義を記述していきます。

データの定義についたは、下記にて様々なデータ定義方法が記述されているので、自分のデータベースのカラムにあった指定をしてみてください。

https://github.com/fzaninotto/Faker

2:seederでファクトリーを設定

次にSeederで、Factoryを設定していきます。

ここも、Laravel8で記述方法が変わった部分かと思います。

まずは、Seederのファイルをコマンドで作成していきます。

 php artisan make:seed ChatMessageTableSeeder 

こちらのコマンドで、 ChatMessageTableSeeder ファイルが作成されます。

ChatMessageTableSeeder の全体を記述しておきます。
ここでのポイントは
ポイント①;eloquentを呼び出す
ポイント②:eloquentからfactoryを呼び出して、データ作成個数を設定する

下記が ChatMessageTableSeeder の全体です。

 <?php

namespace Database\Seeders;

use Illuminate\Database\Seeder;

// ChatMessage を呼び出し
use App\Models\ChatMessage;

class ChatMessageTableSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        ChatMessage::factory()->count(3)->create();
    }
}

 

->count(3) このメソッドで、作成するデータの個数を指定します。

3: DatabaseSeeder で seeder callする

ここまで、きたら後はすんなりいくと思います。

デフォルトである、DatabaseSeeder ファイルに対して、 ChatMessageTableSeeder を呼び出します。

記述方法は、public function run()メソッドの中でcallします。

     public function run()
    {
        $this->call(ChatMessageTableSeeder::class);
    } 

4: php artisan db:seed

最後に、php artisan db:seed をしてください。
これで、データベースを確認してください。
Factoryで指定したテストデータが作成されているかと思います。

以上です。
Laravel8で、変更された部分があるので、解説していきました。
是非、Factoryを使って、テストデータを作成してみ下さい。

DockerでLaravel構築した後に、bootstrapを導入。エラー祭りを解決

Dockerを使って、Laravelを起動しています。
昔、xamppでLaravelでbootstrapした際は、すんなりいったと思うのですが、
今回は色々なエラーに苦しんだので、記録して残しておきます。

Dockerの環境は、docker-composeを利用して、
php, nginx, mysqlを別々のコンテナで起動しています。

ざっくりとした流れはこちらです。

・php へbashでアタッチする
・node.jsをインストール
・laravel/ui導入
・bootstrap導入
・npm を install & run

php へbashでアタッチする

まずは、Dockerコンテナのphpの中に入ります。
php のコンテナ名はphp としております。

docker-compose exec php bash

cd コマンドを使って、Laravelアプリケーションのルートディレクトリへいきます。
artisan , composer などが存在するディレクトリです。

node.jsをインストール

その階層で、下記コマンドを別々に打ち込んでいきます。

apt-get install -y gnupg
curl -sL https://deb.nodesource.com/setup_10.x | bash -
apt-get install -y nodejs

laravel/ui導入

 composer require laravel/ui 

bootstrap導入

 php artisan ui bootstrap 

npm を install & run

 npm install && npm run dev 

そこで、下記のようなエラーがでてきました。

npm WARN deprecated popper.js@1.16.1: You can find the new Popper v2 at @popperjs/core, this package is dedicated to the legacy v1
 npm ERR! code ENOENT
 npm ERR! syscall rename
 npm ERR! path /work/app/node_modules/.vue-loader.DELETE/node_modules/source-map
 npm ERR! dest /work/app/node_modules/vue-loader/node_modules/source-map
 npm ERR! errno -2
 npm ERR! enoent ENOENT: no such file or directory, rename '/work/app/node_modules/.vue-loader.DELETE/node_modules/source-map' -> '/work/app/node_modules/vue-loader/node_modules/source-map'
 npm ERR! enoent This is related to npm not being able to find a file.
 npm ERR! enoent
 npm ERR! A complete log of this run can be found in:
 npm ERR!     /root/.npm/_logs/2020-10-06T03_43_21_673Z-debug.log

 こちらを見てみると、似たようなエラーが….

https://stackoverflow.com/questions/49651221/npm-enoent-no-such-file-or-directory-rename

 rm package-lock.json 

一度、package-lock.json を削除した後に
再度、

npm install && npm run dev 

これで、いけました!

Dockerコンテナを全て、ローカルホスト環境へコピー

dockerを学んでいるときに、dockerコンテナのファイルをローカルホストにコピーして中身を確認したいとき、ありませんか。
どうしてもLinuxコマンドでディレクトリ移動しているだけだと確認しづらい状況があると思います。

【ポイント】Dockerコンテナを全て、ローカルホスト環境へコピー

・docker コンテナをホストへコピーする方法を知る
・ローカルの権限が必要とされる場合がある(powershell編)

docker コンテナをホストへコピーする方法

docker cp コマンドでコンテナからホストへコピーすることが出来ます。
使い方は、

docker cp <コンテナID>:/<コンテナのディレクトリ> /<コピー後のディレクトリ名>

例えば、

docker cp d8c238b5de69:/ /dockercopy

みたいな感じです。
全ディレクトリをコピーしたいので、「/」で、ディレクトリ宣言しています。

ローカルの権限が必要とされる場合がある(powershell編)

これで実行完了できるかな?と思ったのですが、思わぬエラーが出ました。

A required privilege is not held by the client.

クライアント側に権限がないということです。
これが、あらゆる環境に対して発生するエラーなのかは、わかりません。

OS:Windows
ターミナル:powershell

の環境にて、発生しました。

色々と調べていたところ、こちらの方の記事を見たところ、powershellを管理者権限で実行したらOKと出ていました。

ということで、powershellを管理者権限にして実行したら正しくコピーされていました。

ディレクトリーがコピーされる場所

windowsのC: 配下にコピーされています。
どこだろう?と少し探したので、こちらも記録しておきます。

docker-compose でnginxに/bin/bashでstarting container process caused “exec: \”/bin/bash\”

docker-composeでnginxのコンテナに入ろうとした場合、/bin/bashを使っても

 docker-compose exec nginx /bin/bash 

下記のようなエラーが表示されました。

exec failed: container_linux.go:349: starting container process caused "exec: \"/bin/bash\": stat /bin/bash: no such file or directory": unknown 

これを

 docker-compose exec nginx sh

で起動させると、入ることができました。

AWS ECRでDocker Loginするまで。AWSCLIを使って。

AWSのECRというサービスをご存知でしょうか。
Dockerを利用して、AWSへデプロイしたい場合にはDocker レポジトリとして利用されるサービスです。

AWSもDockerも学習したての頃、最初のログインで躓いてしまいました。
その時の、躓きポイントを紹介して参ります。

ポイント:
・AWS CLIでコマンドからログインしよう
・ログインする場合には、config でprofileを設定し、活用しよう
・ログインするのは、AWSのアカウント情報(IAM情報)でECRへログイン

こちらの話でお届けします。

今回、一番参考になると思われる読者の方は

「詳しく分からないが、ECRにログインしなくては。でも、ログインって何情報を使って、どういうコマンドでログインすればいいのか。」といった疑問を持った方かと思います。

参考記事:

全体を通して、参考にさせて頂いた記事は、「AWS CLIを使ってECRにDockerイメージを登録する」です。

1:AWS CLIでコマンドからログインしよう

まずは、AWS CLIを使っていきましょう。AWSのGUI(コンソール画面)でも進めていけるのでしょうが、サンプル情報もCLIの情報を基にしているものが多いですし、ログとして残していけるCLIをお勧めします。

windowsでCLIを活用していくためには、こちらを参考にしました。
このまま進めていけば、CLIの活用はすんなり進めることができました。

2: ログインする場合には、config でprofileを設定し、活用しよう

CLIで、config情報を設定することが出来ます。下記コマンドを使います。

aws configure

これ、何のために実行するのか??と、疑問の方もいるかもしれません。
ECRに限らず、CLIからAWSサービスを利用していく際に、ユーザーのログイン情報などを使うシーンがあります。
その際に、いちいち情報を打ち込んだり、コピペしたりする手間を省く目的で使われます。

で、1点気に掛けるといいのは、config情報の登録をuser名を付けて同時に設定することが可能です。
( 複数のconfig情報を登録して、利用する場合に用いる必要があるわけですね。 ) 何も設定しないと、defaultという名称になっているはずです。

コマンドとしては下記です。

aws configure user1( 任意のusername )

3: ログインするのは、AWSのアカウント情報(IAM情報)でECRへログイン

さぁ、それでは、今回の記事の本題です。ここから、ECRへログインしていきます。CLIでのコマンドは下記です。

aws ecr get-login-password --profile 設定A | docker login --username AWS --password-stdin 設定B

私は、最初に勘違いしていたのが、docker loginに含めるべき情報が、docker hubの情報だと勘違いしていました。正直、冷静に考えればそんなハズもないのですが。
色々な情報が欠けていると、見当はずれ間違いを起こしてしまうものですね。

で、ここでログインするべき情報はAWSのアカウント情報(IAM情報)です。

上記のコマンドで、利用者個別で変更する部分は、設定A・設定Bです。

注意して頂きたいのは、CLIのversionによって、コマンドが異なってきます。
今回、使用しているコマンドは v2のコマンドです。
こちらの記事を参考にしてます。

設定A:configで設定した、profile名称。

設定A:configで設定した、profile名称。
>2: ログインする場合には、config でprofileを設定し、活用しよう
にて、解説した部分です。
ここで設定した、aws configure user1 であれば、設定Aにuser1と記します。

設定B: ECRのリポジトリで作成したURI

設定Bは、ECRでレポジトリを作成した際のURIを活用します。今回の記事では、URIの紹介をしておりませんが、冒頭にお伝えした記事にてその作り方が紹介されております。非常に簡単に作れると思います。そこで作成したURIを貼り付けます。

AWSのコンソール画面でもURIは確認することができます。

以上で、コマンドを実行して、

Login Succeeded

と表示されればログイン完了です。

DockerでMysqlへログイン ERROR 1045 (28000): Access denied for user

Dockerの環境構築に手こずっておりました。
今回の記事は、先日の記事の続きです。

mysqlの中に入ったあとに、

docker exec -it db-host bash

mysqlにrootユーザーとしてログインしようとしたら、次のようなエラーメッセージが表示されました。

root@5c001e56e8bc:/# mysql -uroot -p
Enter password: 
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)

Laravelの.envの確認をして、password設定したいましたが、うまくいきません。

結論:docker-compose.yml の MYSQL_ROOT_PASSWORDを確認

mysqlへのroot権限での情報は、docker-compose.yml > environment: > MYSQL_ROOT_PASSWORD: で設定していたのです….

理解せずに、進めると躓きますね。

ということで、ここで設定したpasswordを反映すると、下記のように入れます。

Welcome to the MySQL monitor.  Commands end with ; or \g.
 Your MySQL connection id is 3
 Server version: 5.7.31 MySQL Community Server (GPL)
 Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
 Oracle is a registered trademark of Oracle Corporation and/or its
 affiliates. Other names may be trademarks of their respective
 owners.
 Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

DockerでLaravelを構築時に、Route設定したのに[404 not found]

Dockerを使ってLaravelの環境構築をしています。
DockerもLaravelもまだまだ理解が浅いなかで、進めています。

今回、解説したいことは、
・Dockerを使ってLaravelを構築
・トップページは表示 (welcom.blade.php)
・ルーティング、コントローラー、ビューを設定(ミスなく)
・新しく設定したルートをリクエストしても[404 not found]になる ★ココ

という状況です。

DockerのLaravel環境構築は、Qiitaで記載されていた下記を参考にさせて頂きました。

https://qiita.com/A-Kira/items/1c55ef689c0f91420e81

( ほぼ)同じようにセットアップしていきました。
上記問題が発生した際に、確認したことは。

ルーティングの設定です。
最初は、
Laravelのルート設定に問題がないのか確認したのですが、問題ありませんでした。

次に、
Webサーバーの確認です。
Webサーバー は、nginxを使っています。
で、Dockerにて、nginxを設定する際に、default.confで設定していた部分を確認しました。

nginx設定は、基本的にはdefault.confで設定していくそうです。
ここで、ルーティングと関係している部分は、 location  です。

元々の設定:

location / {     root /var/www/public;     index  index.html index.php;     } 

この場合だと、ルートディレクトリのみ表示できる状態です。

下記のように変更すると、設定した他のルートにもアクセスできました。
loacationの設定は 他にも、色々とありそうです。

  location / {
    root /var/www/public;     
  index  index.html index.php; 
    try_files $uri $uri/ /index.php?$query_string;    
  } 

これを変更したあとは、
再度、
・ビルドを実施。(キャッシュは使わずに)
・コンテナ起動
をして、確認してみましょう。

docker-compose build --no-cache
docker-compose up -d

TravisCI GithubのPush しても’Could not parse’テストが開始しない件

Travis CIを利用しています。
TravisCIの詳しい説明は省略しますが、今回はGithubからPushした際に自動でテスト実行できる環境を構築していきます。

今回、直面した問題はGithubでPushしてもTravisCIが実行されなかった件です。
何度か、Pushしてテストが実行されていたのですが、急に反応しなくなりました。

まず、確認したのは、more option > request

travis_more_option

したのすると、”Could not parse” となりエラーの状態になっていました。

色々と調べていくと、同じようにエラーになっている人がいました。

https://stackoverflow.com/questions/50551277/could-not-parse-travis-yml

ここで紹介されていたのは、.travis.ymlの書き方でのエラーとのことです。
で、下記の便利ツールが紹介されていました。
Pushする前に、.travis.ymlにエラーがないかを判定してくれるツールです。

ここで実行すると、エラーに該当する部分を指摘してくれます。
是非、確認してみてください。

おそらく、インデントや、タブ、スペースなどでエラーになっていることが多いのではないでしょうか。

.travis.yml のcould not parse エラー部分を発見するツール

こちらがエラー判定の便利ツール

http://www.yamllint.com/

heroku CLIをpowershellで起動 Windows編

Docker での開発環境構築は、windowsよりも、macの方がやりやすいのでしょうか。

Dockerを使い始めています。
ひとまず、デプロイ先として、herokuを使おうとして進めていました。

The Heroku CLIをwindowsにてインストールして、windows、powershellにて、herokuを起動させようとしました。

heroku CLIのインストール先
https://devcenter.heroku.com/articles/heroku-cli

インストール自体は、シンプルです。
インストール完了後に、
powershellで、

heroku --version

をしたところ、コマンドレット XXXXXXXXXXXXXXX
herokuがコマンドが無い状態でした。。。

試しに、コマンドプロンプトを開いて、

heroku --version
heroku/7.43.0 win32-x64 node-v12.16.2

heroku CLIをpowershellで起動させるためしたこと

powershellを一度閉じて、再度起動して、heroku –version をするとちゃんと、コマンドが反応しました!!!

これでも、20分くらい彷徨ったので、誰かのために残しておきます。

Laravelで画像をUploadして、表示させる方法

Laravelで画像をUPLOADして、表示させる方法を紹介します。
今回は、POSTで画像をUploadしていきます。
・画像のUpload方法
・画像の表示方法
を紹介していきます。

画像をUploadするための流れを解説

・formを利用して、画像をUpload
・UploadするファイルのPathをデータベースへ保存

formを利用して、画像をUpload

まずは、formを利用して画像をUploadします。
formで、Uploadされた画像は、storageの配下にUPされます。

View____________________

<form method="POST" action="/imageUpload" enctype="multipart/form-data">
{{ csrf_field() }}
<input type="file" id="file" name="profile" class="form">
<button type="submit">アップロード</button>
</form> 

ポイント;
・input type=”file”
・enctype=”multipart/form-data

ファイルアップロードをする場合input要素はを使い、その親のform要素には以下のようにenctype=”multipart/form-data”と書く必要があります。

ROUTE____________________

Route::post('/imageUpload', 'mypageContactController@imageUpload') 

ポイント;
・formのactionが、postで指定するアクション内容となる。

UploadするファイルのPathをデータベースへ保存

Uploadされた画像を呼び出すために、Uploadする画像のPath名称を設定して、そのPathをデータベースに登録する必要があります。

$file_name = time() . '.' . request()->file->getClientOriginalName();
// fileの名称を決定します。
// Uniqueになっていることが重要なので、time()を接頭に追記

$request->file('file')->storeAs('public',$file_name);
// storageは以下のpublicディレクションに、 $file_name で保存



//ここからは、データベースにファイルがUpされているPathを保存
$imagepath = '/storage/' . $file_name;


$loginId = Auth::id();
$profileInfo = User::find($loginId);
//Modelを活用

$profileInfo->imagepath = $imagepath;
// imagepathをデータベースへ保存
$profileInfo->save();

return redirect()->action(
'mypageContactController@profile'
); 

パス名が public/xxxxxxxxxx.jpg となるので不要な public/ の部分を削除しています。

画像を表示するための流れを解説

・シンボリックリンクの作成
・<img src=”path名称”>に、pathを代入する

シンボリックリンクの作成

Laravelは、publicディレクトリ配下に存在するファイルしか、表示することができません。しかし、アップロードしたファイルは/storage/appの下にあるためアクセスすることができません。
/publicディレクトリと/storage/appディレクトリとの間でリンクを持たせる必要があります。
それを実行してくれるのが、シンボリックリンクです。

やり方は、いたってシンプルです。
コマンドで下記を実行してください。

 $ php artisan storage:link 

画像を表示させる<img src=”path名称”>に、pathを代入する

あとは、画像を表示させたい場所で、保存したPathを呼び出してあげればよいです。上記で、App\Model\User {{ imagepath }} のカラムへ、Pathをデータベースへ保存しました。

Viewで下記を呼び出してあげればOKです。
※ただし、Viewで呼び出すために、Controllerから、profileInfo(Userのデータ)をView側へcompactで送ってあげることが前提です。

@if(isset( $profileInfo->imagepath ))
<img src="{{$profileInfo->imagepath}}">     
@else
@endif