Hello, World!

難しいことは書けません

Laravelとdockerの環境でMailHogを使ってメール送信テストを実行するには

前までlogにメールを吐き出していたけど、MailHogを使おうということになりました

MailHogのコンテナを作る

今回は以下のようにすでにdocker-compose.ymlにMailHogのことが書かれていました

### Mailhog ################################################
    mailhog:
      build: ./mailhog
      ports:
        - "1025:1025"
        - "8025:8025"
      networks:
        - frontend
        - backend

Dockerを再起動させる

laradockディレクトリの中で以下のコマンドを実行

docker-compose up -d mailhog

docker ps でMailHogのコンテナが新しく作成されているか確認します
f:id:eeko-amaryllis:20190620155428p:plain:w600

http://localhost:8025 にアクセスすると以下のようが画面が表示されていればOK
f:id:eeko-amaryllis:20190620155934p:plain:w600

.env.dusk.localのメール設定

MAIL_DRIVER=smtp
MAIL_HOST=mailhog
MAIL_PORT=1025
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null

あとはテストを実行してメールがhttp://localhost:8025に届いていればOK

(もしphp artisan config:cache なんてしてしまったら、php artisan cache:clearをすればいい👏)

あとローカルでMailHog使うならbrewで入れることができるらしい

// インストール
brew install mailhog

// 起動
brew services start mailhog

はじめてテストを書きました

初めてテストを書いたんですよ、簡単なのですが
なので忘れないようにメモしておきます

テスト生成と実行コマンド

環境はLaravelで、PHPUnitで今回はログイン画面のテストを書いていこうと思います
まずテストの生成

php artisan make:test LoginTest

tests/Feature/LoginTest.php にファイルが作られます

テストを実行するには、ターミナルでphpunitコマンドを実行すれば大丈夫です

phpunit

テストファイルの命名規則

テストを作る際にルールがあります
・テストファイルはファイル名を、hogeTest.phpとすることでテスト対象となる
・メソッドは、testHoge()とするか、@testコメントをつけておくとtestと認識される

上記をふまえてテストを書いていきます

テストコード

まず前のテストデータが次に実行されるテストへ影響をあたえないように、各テストが終了するごとにデータベースをリセットさせるためトランザクションを使います

use DatabaseTransactions;

次にユーザーデータを作ります
テストを実行する前に行いたいのでsetUp()に書いていきます

<?php

    /**
    * @var \App\Models\User;
    */
    public $user;
    /**
    * Setup the test environment.
    */
    protected function setUp()
    {
        parent::setUp();
        $this->user = factory(User::class)->state('active')->create();
    }

UserFactory.phpのコードは省略します

あと factory()って何?ってなったかと思います
factory()とは

テスト実行前に、何件かのレコードをデータベースに挿入する必要があります。こうしたテストデータを作る時に、手動でそれぞれのカラムへ値を指定する代わりに、Laravelではモデルファクトリを使用します。
引用元:https://readouble.com/laravel/5.5/ja/database-testing.html

なるほど

準備は終わったのでテストコードを書いていきます

<?php
    /**
    * @test
    */
    public function ログインしていない状態ユーザーのみログイン画面が表示される()
    {
        //ログインしてない状態で/loginにアクセスした場合
        $response = $this->get('/login');
        $response->assertStatus(200);

        //ログインしている状態で/loginにアクセスした場合
        $response = $this->actingAs($this->user)->get('/login');
        $response->assertStatus(302);
    }

actingAs()を利用することで作ったユーザデータを認証済み状態にすることができ
ログインしてない状態で/loginにアクセスした場合、クライアントのレスポンスが200
ログインしている状態で/loginにアクセスした場合、クライアントのレスポンスが302
ならOKというテストを作りました

ログインしている状態で/loginにアクセスした場合クライアントから帰ってくるレスポンスが何番なのかわからない場合は、普通に調べてもいいけどChromeの検証で
Network → Preservelogをチェック → /loginにアクセス → 下の項目のloginをクリック → Status Codeを確認
すればOK
f:id:eeko-amaryllis:20190613095441p:plain:w600

実行結果
f:id:eeko-amaryllis:20190612182905p:plain:w600
緑になったので大丈夫

以下全体コード

<?php

namespace Tests\Feature;

use Tests\TestCase;
use App\Models\User;
use Illuminate\Foundation\Testing\WithFaker;
use Illuminate\Foundation\Testing\DatabaseTransactions;

class LoginTest extends TestCase
{
    use DatabaseTransactions;

    /**
    * @var \App\Models\User;
    */
    public $user;
    /**
    * Setup the test environment.
    */
    protected function setUp()
    {
        parent::setUp();
        $this->user = factory(User::class)->state('active')->create();
    }

    /**
    * @test
    */
    public function ログインしていない状態ユーザーのみログイン画面が表示される()
    {
        $response = $this->get('/login');
        $response->assertStatus(200);

        $response = $this->actingAs($this->user)->get('/login');
        $response->assertStatus(302);
    }
}

プログラムを修正したら自動的にHerokuにも反映してほしい

herokuに変更箇所をpushしようとしたらエラーがおきた
f:id:eeko-amaryllis:20190204142619p:plain:w600
gitがリモートのリポジトリを参照出来ていないのが原因らしいので、リモートにherokuを追加します
まず .git/config を確認するとremoteの参照先にherokuがないので
f:id:eeko-amaryllis:20190204142737p:plain:w600

以下のコマンドで登録する
参考:Heroku にある Git リポジトリを楽に remote に設定する - Qiita

heroku git:remote --app appname

コマンド実行後の.git/config
f:id:eeko-amaryllis:20190204142749p:plain:w600
ちゃんとリモートにheroku追加できてる
これでデプロイできた

MySQLWorkbench version 8.0.15でER図を出力したい

以下参考にしたサイトと少し見た目が違ってたのでメモ
qiita.com

MySQL Workbenchを起動した時
左側の2番目のアイコンをクリックして、">" マークをクリックした時に"Create EER Model From Databae"を選択するとER図出力できる
f:id:eeko-amaryllis:20190411140239p:plain

gitからcloneしてきたRailsアプリを動かしたい

gitからcloneしてきたRailsアプリを動かすにはどうしたかをまとめた(前半少しぬけてる気がする)

cloneしてきてlocalhostで見れるまで

まずRailsアプリをcloneしてきて、cloneしてきたディレクトリに移動し、server起動

git clone git@github.com:username/app_name.git
cd app_name
rails s

しかし
can't find gem bundler (>= 0.a) with executable bundle (Gem::GemNotFoundException) ~~
とエラーがでる
調べると、とりあえず以下のコマンドを打てばいいのかな?
参考:can&#39;t find gem bundler (&gt;= 0.a) with executable bundle 対応 - Qiita

bundle install --path vendor/bundle

今度はTraceback (most recent call last): ~~~ とエラー
原因はGemfile.lockに記載されているBUNDLE WITH(1.17.1)のバージョンが、インストールされているbundlerのバージョンと異なっていることらしい
参考:can&#39;t find gem bundler (&gt;= 0.a) with executable bundle 対応 - Qiita

確認すると今インストールされてるバージョンは 2.0.1で
f:id:eeko-amaryllis:20190204142034p:plain:w600
今回のRailsアプリのGemfile.lockを見ると1.17.1
f:id:eeko-amaryllis:20190204142203p:plain:w600
なので、それにバージョンを合わせるために再インストールするコマンドを実行

gem install bundler -v 1.17.1

特にエラーも出ずうまくいったので、以下のコマンド実行

bunble install

これもまたうまくいったかんじなので、server起動しhttp://localhost:3000を確認すると、画面に大きくActiveRecord::PendingMigrationError とエラーが出たのでmigrateするため以下のコマンドを実行
参考:ActiveRecord::PendingMigrationError と言われた時の解決方法 - Qiita

bundle exec rake db:migrate 

これでcloneしてきた環境で動かすことができる

どうにかして楽にbladeファイルを作成したい

LaravelでWebサービスを作成した際にbladeファイルを作るのがすごくめんどくさかった
いちいち以下のようなコマンドを打っていた

mkdir -p resources/views/shop
mkdir -p resources/views/menu

touch resources/views/shop/index.blade.php
touch resources/views/menu/list.blade.php

めちゃくちゃめんどくさい

なのでテキストファイルを読み込んでそこに書かれているディレクトリとbladeファイルを作ってくれるコードを書いた
shellで書いてもいいのだけど、なんとかくPerlで書いてみようと思い書いてみた

file_list.txt
resources/views/shop/index.blade.php
resources/views/shop/shop_information.blade.php
resources/views/shop/shop_introduction.blade.php
resources/views/shop/shop_other.blade.php
resources/views/menu/sort.blade.php
resources/views/menu/list.blade.php
resources/views/menu/add.blade.php
resources/views/menu/edit.blade.php
resources/views/menu/delete.blade.php
resources/views/staff/sort.blade.php
resources/views/staff/list.blade.php
resources/views/staff/add.blade.php
resources/views/staff/edit.blade.php
resources/views/staff/delete.blade.php
make_file_dir.pl
#!/usr/local/bin/perl

my $make_dir_command = 'mkdir -p';
my $make_file_command = 'touch';
open(DATAFILE, "< file_list.txt") or die("error :$!");

if ($?) {
  print "エラーが発生しました。\n";
  print "$make_file_command:$!", "\n";
} else {
  while (my $data = <DATAFILE>){
    chomp($data);

    if ($data =~ /\//) {
      foreach my $row_data($data){
        my $line = $row_data;
        #末尾から/以降を削除
        $row_data =~ s/\/[^\/]*$//;
        system("$make_dir_command $row_data");
        system("$make_file_command $line");
        print "--実行コマンド--\n";
        print "$make_dir_command $row_data\n";
        print "$make_file_command $line\n";
      }
    } else {
      print "/が含まれていません。\n";
    }
  }
}

実行結果

$ perl make_file_dir.pl
--実行コマンド--
mkdir -p resources/views/shop
touch resources/views/shop/index.blade.php
--実行コマンド--
mkdir -p resources/views/shop
touch resources/views/shop/shop_information.blade.php
--実行コマンド--
mkdir -p resources/views/shop
touch resources/views/shop/shop_introduction.blade.php
--実行コマンド--
mkdir -p resources/views/shop
touch resources/views/shop/shop_other.blade.php

... 省略 ...

もしかしたら初めのif文はいらないかもしれないけど一応
テキストファイルのデータが変数$dataに入っていて、foreachでデータ1行1行(resources/views/shop/index.blade.php などが)変数row_dataに入ってる
そして、一旦そのデータを変数lineに保持
次に変数row_dataの末尾の"/"以降の部分(index.blade.phpなど)を削除する
ここで変数row_dataにはディレクトリ名だけの値が入っている(例:resources/views/shop)
system() で指定したコマンドを実行
(参考:http://www.tohoho-web.com/perl/cmd.htm
ディレクトリを作成している

$make_dir_command $row_data

ディレクトリが先に作られているので、ファイルを作成している

$make_file_command $line

これでできた!

シェルでMySQLを実行し、csvファイルに書き出す

descでカラム一覧を表示して、その結果をcsvファイルに出力したかった。
けどそのファイル出力を50回しないといけなくてとても面倒なのでシェルでかいてみた。
columns_list.txtにはカラム名が書かれているテキストファイル。
以下シェルプログラム

#!/bin/bash

while read columns
do
  sql="desc $columns"
  mysql -uroot -proot -e "$sql" db_name > ~/columns_csv/$columns.csv
done < columns_list.txt


書き出せたけどWarningがでる。

[Warning] Using a password on the command line interface can be insecure.

/Applications/MAMP/conf/my.cnfで以下のプログラムを追加したけど、Warningは消えなかったなぁ🤔

[client]
user = root
password = root
host = localhost


参考
【シェルスクリプト】ファイルの中身を一行ずつ読み込む方法 | server-memo.net

MySQL5.6のUsing a password on the command line interface can be insecureの対応 - 文系プログラマによるTIPSブログ