20200927のlaravelに関する記事は10件です。

【Laravel】hasOne

リレーション

主キーと外部キー

主キーはテーブルに一つ
外部キーはテーブルに複数
主キーと外部キーによりリレーションしている

hasOne

1体1のリレーション
一つの外部キーしか取得できない

準備

モデルクラスにテーブルの単数形としてメソッドを用意して以下のように書く

function table(){
  return $this->hasOne('App\Table');
}

コントローラからの呼び出しの際には以下のようにする

    function test(){
        $items=Table::all();
        dd(Member::find(10)->table);
    }

メソッドだから

//こうじゃなくて
dd(Member::find(10)->table);
//こうじゃないの?
dd(Member::find(10)->table());

と悩んだが、()はつけないことに注意

Member::find(10)->tableのなかにTableモデルのインスタンスが入る

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

Lalavelでメールの送信機能を実装しようとしたらハマった話。

https://www.hypertextcandy.com/laravel-tutorial-authentication-part-2/
こちらの記事を参考に、Laravel(ver.5.7)でメールの送信機能を実装しようとしたらはまりました。

何度コードの記載をし直しても認証できませんとのエラーが、パスワードの再設定のボタンを押すと出されてしまう。

Swift_TransportException in AbstractSmtpTransport.php line 383:
Expected response code 250 but got code "530", with message "530 5.7.1 Authentication required"

結論から言うと、.envを変更した際にキャッシュをクリア(php artisan config:cache)していないのが原因でした。config/mail.phpの設定も一部変更する必要があった模様。
これらの合わせわざではまりました。

MAIL_DRIVER=smtp
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=ここに Username を記載する
MAIL_PASSWORD=ここに Password を記載する
MAIL_ENCRYPTION=null
MAIL_FROM_ADDRESS=todoapp@email.com
# ここに自分の持っているメールアドレスを記載することで、自分のメールアドレスからパスワードの再発行を申請した人に新しいメールアドレスが送られます。
MAIL_FROM_NAME="ToDo App"
# ここはなんでもOKです。
mailtrap.ioのデータ。
MAIL_MAILER=smtp
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=ここのデータをコピーする
MAIL_PASSWORD=ここのデータをコピーする。
MAIL_ENCRYPTION=tls

カリキュラムだとMAIL_DRIVERの定数の定義が微妙に違いました。

MAIL_DRIVER=smtp
MAIL_MAILER=smtp

とりあえずmailtrapの記載に合わせて「MAIL_MAILER=smtp」と.envに記載しました。

その後、キャッシュをクリアしてみてもエラーがでる。。。

config/mail.phpを確認してみる。
絶対に必要かはわからないが、config/mail.phpをみると確実らしい。

mail.php
    'driver' => env('MAIL_DRIVER', 'smtp'),

これだ!

mail.php
    'driver' => env('MAIL_MAILER', 'smtp'),

記載を変更した時は、忘れ図にキャッシュをクリア!

$php artisan config:cache
Configuration cache cleared!
Configuration cached successfully!

記載しなおしてキャッシュをクリアしたら元に戻りました。
ちゃんとメールも届いてる。

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

Laravelのクエリビルダの中にCASE文を使いたい場合の書き方

laravel 7.0
PostgreSQL 12.2

下記コードのようにselectRaw()を使うことで、クエリビルダの記述中に生SQL文を使うことが可能です。

例)
Usersテーブルにgender_idというカラムがり、gender_idの値から性別を文字列に変換して取得したいと思った場合の処理。

$result = $users->select('name')
                  ->selectRaw("(CASE gender_id WHEN 0 THEN "男性" WHEN 1 THEN "女性" END) AS gender")
                  ->get();

データとしては下記のようになります。






name gender
山田太郎 男性
山田花子 女性
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[Laravel] プロジェクト開始までの忘備録

概要

Laravel プロジェクトを開始するまでのコマンドをまとめた個人メモ。

前提条件

プロジェクトの開始

Version6系を使用し、tasklistというプロジェクト名で作成する

$ composer create-project --prefer-dist laravel/laravel tasklist ^6.0

DB作成

Dockerを使用し、mysql コンテナを立ち上げる。

$ docker run --name mysql -e MYSQL_ROOT_PASSWORD=mysql -d -p 3306:3306 mysql
$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                               NAMES
4ded8e15debd        mysql               "docker-entrypoint.s…"   6 days ago          Up 6 days           0.0.0.0:3306->3306/tcp, 33060/tcp   mysql

プロセスで表示されたCONTAINER IDを使用し、コンテナに接続後DBの作成を行う
mysqlのパスワードはMYSQL_ROOT_PASSWORD引数で指定した値。

$ docker exec -it 4ded8e15debd86c73e637b0c612bf30f0cd9de0aec04b4c09a0f53a6fa16f35d bash
root@4ded8e15debd:/# mysql -u root -p -h 127.0.0.1
Enter password: mysql
mysql> DATABASE tasklist;
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| tasklist           |
+--------------------+
5 rows in set (0.03 sec)

DB 接続情報の定義

プロジェクト配下の .env ファイルで接続情報を定義する。
接続情報は個々の環境に合わせて変更すること。

$ cd tasklist 
$ vim .env

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=tasklist
DB_USERNAME=root
DB_PASSWORD=mysql

DB接続の確認

Webアプリが正常にDB接続できているか確認を行う。
以下のように表示されている場合接続できている。

$ php artisan tinker
Psy Shell v0.10.4 (PHP 7.4.10 — cli) by Justin Hileman
>>> DB::reconnect();
=> Illuminate\Database\MySqlConnection {#3233}

タイムゾーンの変更

デフォルトではUTCのため、Asia/Tokyoに変更する。

$ vim config/app.php

'timezone' => 'Asia/Tokyo',

アプリの起動

内部サーバを起動させる。
デフォルトで用意されている welcome.blade.php のviewが表示される

$ php artisan serve --host=127.0.0.1 --port=8080 

備考

コンテナを停止する際は以下コマンドを実行すること。

$ docker stop { CONTAINER ID }
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[Laravel] プロジェクト開始までのコマンド忘備録

概要

Laravel プロジェクトを開始するまでのコマンドをまとめた個人メモ。

前提条件

プロジェクトの開始

Version6系を使用し、tasklistというプロジェクト名で作成する

$ composer create-project --prefer-dist laravel/laravel tasklist ^6.0

DB作成

Dockerを使用し、mysql コンテナを立ち上げる。

$ docker run --name mysql -e MYSQL_ROOT_PASSWORD=mysql -d -p 3306:3306 mysql
$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                               NAMES
4ded8e15debd        mysql               "docker-entrypoint.s…"   6 days ago          Up 6 days           0.0.0.0:3306->3306/tcp, 33060/tcp   mysql

プロセスで表示されたCONTAINER IDを使用し、コンテナに接続後DBの作成を行う
mysqlのパスワードはMYSQL_ROOT_PASSWORD引数で指定した値。

$ docker exec -it 4ded8e15debd86c73e637b0c612bf30f0cd9de0aec04b4c09a0f53a6fa16f35d bash
root@4ded8e15debd:/# mysql -u root -p -h 127.0.0.1
Enter password: mysql
mysql> CREATE DATABASE tasklist;
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| tasklist           |
+--------------------+
5 rows in set (0.03 sec)

DB 接続情報の定義

プロジェクト配下の .env ファイルで接続情報を定義する。
接続情報は個々の環境に合わせて変更すること。

$ cd tasklist 
$ vim .env

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=tasklist
DB_USERNAME=root
DB_PASSWORD=mysql

DB接続の確認

Webアプリが正常にDB接続できているか確認を行う。
以下のように表示されている場合接続できている。

$ php artisan tinker
Psy Shell v0.10.4 (PHP 7.4.10 — cli) by Justin Hileman
>>> DB::reconnect();
=> Illuminate\Database\MySqlConnection {#3233}

タイムゾーンの変更

デフォルトではUTCのため、Asia/Tokyoに変更する。

$ vim config/app.php

'timezone' => 'Asia/Tokyo',

アプリの起動

内部サーバを起動させる。
デフォルトで用意されている welcome.blade.php のviewが表示される

$ php artisan serve --host=127.0.0.1 --port=8080 

備考

コンテナを停止する際は以下コマンドを実行すること。

$ docker stop { CONTAINER ID }
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

HTTPメソッド 私的まとめ

RestfulではCRUDは同じアドレスでHTTPメソッドに違いで処理が分けられる

HTTPメソッド CRUD
GET Read。レコード取得
POST Create。レコード新規作成
PUT Update。レコード更新
DELETE Delete。レコード削除

HTTPメソッド一覧

HTTPメソッド 意味
GET 指定したリソースの表現をリクエストします。 GET を使用するリクエストは、データの取り込みに限ります。
HEAD GET リクエストと同じレスポンスを求めますが、レスポンス本文はありません。
POST 指定したリソースに実体を送信するために使用するメソッドであり、サーバー上の状態を変更したり、副作用が発生したりすることがよくあります。
PUT 対象リソースの現在の表現の全体を、リクエストのペイロードで置き換えます。
DELETE 指定したリソースを削除します。
CONNECT 対象リソースで識別されるサーバーとの間にトンネルを確立します。
OPTIONS 対象リソースの通信オプションを示すために使用します。
TRACE 対象リソースへのパスに沿ってメッセージのループバックテストを実行します。
PATCH リソースを部分的に変更するために使用します。

参考:HTTPリクエストメソッド

Laravelのリソースコントローラのリソースアクションは以下

処理 アクション
一覧表示 index
新規作成 create,store
レコード表示 show
更新処理 edit,update
処理処理 destroy
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Laravel7継承レイアウトの基本を図解してみた

絵に描いてみた

LaravelのBlade式のレイアウトに関して、巷には教科書や公式ドキュメントなど説明がありますが、文学よりも漫画で育ってきた私は理解するのに思ったより苦労しました。
その時、こんな図解があったらいいな...と思っていた絵を描いてみました↓

Laravel継承レイアウト (1).jpg

このindex.blade.phpブラウザで表示するとこうなります↓
スクリーンショット 2020-09-27 16.12.24.png

文字でまとめると

  • ベースレイアウト(親)で用意できるもの
    @yield(''):子のsectionやsection+endsectionを受け付ける。
    @section('') + @show:子のsection+endsection(+parent)を受け付ける。感覚的にはendsectionで締められそうですができません。

  • 継承レイアウト(子)で使えるもの
    @extends(''):これ無いと始まらない
    @section(''):yieldに対して使う。
    @section('') + @endsection:これもyieldに対して使う。
    @section('') + @endsection (+@parent):section-showに対して使う。parentが使えることも特徴。

最後に

以上です。お役に立てれば幸いです。また、何かご指摘があればぜひお願いします。

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

CORSについて

やっていたこと

nuxtからlaravelに向かってリクエストを送ったがエラーが発生。

Access to XMLHttpRequest at 'http://0.0.0.0:23450/api/register' from origin 'http://0.0.0.0' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

corsポリシーに反しているから、ブロックしたぞと言われている。
corsで調べると「別々のoriginがやりとりできるようにすること」だとか。
originとはドメイン+ポート+urlのこと。
https://developer.mozilla.org/ja/docs/Web/HTTP/CORS

解決方法

laravel側で受け取れるようにmiddlewareを設定する。
参考はCORSについて理解してLaravel5.6で対応する

自作のmiddlewareを作成して、全てのrouteで発動させる

<?php

namespace App\Http\Middleware;

use Closure;

class Cors
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        return $next($request)
        ->header('Access-Control-Allow-Origin', 'http://0.0.0.0')
        ->header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS')
        ->header('Access-Control-Allow-Headers', 'Content-Type');
    }
}

やってみたけど、うまくいかなかったこと

・nuxt側でproxyという機能を使ったcorsの設定
Vue.jsとAPIサーバとのaxiosでCORSに引っかかった時のProxyを使った回避方法

【Nuxt.js】データベースにCORSで接続できない?ならば @nuxtjs/proxy を使いなさい【手順】

corsの勉強になった参考文献

CORSについて理解してLaravel5.6で対応する
CORSまとめ
【Rails6】Gem rack-corsを導入してCORS設定を行う(オリジン・CORSとは何か)
CORS を分かってないから動くコード書いて理解する
Preflight request (プリフライトリクエスト)

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

【Laravel】Collectionのrejectメソッド

はじめに

今回もLaravelのCollectionのメソッドについてまとめたいと思います。

rejectメソッドで条件に合わないものを除外してデータ取得する

Collectionの中から条件に合わないものを除外してデータ取得することができます。

$collection = collect([
    ['id' => 1, 'name' => '山田', 'age' => 18],
    ['id' => 2, 'name' => '佐藤', 'age' => 38],
    ['id' => 3, 'name' => '小林', 'age' => 25],
    ['id' => 4, 'name' => '鈴木', 'age' => 34],
    ['id' => 5, 'name' => '田中', 'age' => 29],
]);

$filtered = $collection->reject(function($values, $key){

    return ($values['age'] < 30);

});
print_r($filtered->toArray());

実行結果は下記になります。

Array
(
    [1] => Array
        (
            [id] => 2
            [name] => 佐藤
            [age] => 38
        )

    [2] => Array
        (
            [id] => 4
            [name] => 鈴木
            [age] => 34
        )

)

※条件式がtrueになるものは除外さます。

おわりに

いかがでしたでしょうか。
rejectメソッドで条件に当てはまるものを除外できるので試してみてください。

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

Well Architected Frameworkを意識して自分なりにアーキテクチャ設計・構築をしてみた。<Route53、ACM編>

HTTPS化

ACM

事前にドメインを取得して、Route53にホストゾーンの作成を行っています。

注意
ALBで利用する証明書はALBのあるリージョンで、Cloudfrontで利用する証明書は必ず「バージニア北部」で取得して下さい。

それではマネジメントコンソールの「Certificate Manager」から証明書の発行を行います。
スクリーンショット 2020-09-26 23.36.46.png

今回は一般的な用途ですので、「パブリック証明書のリクエスト」を選択して下さい。
スクリーンショット 2020-09-26 23.36.59.png

ドメイン名の登録を行います。

この時、複数のドメインを追加することも可能です。
また、「*.example.com」のようにワイルドカードで追加することも可能ですので、サブドメインを使うのであれば、追加しても良いでしょう。

「*.example.com」で発行を行った場合、「example.com」は適用されないので、別で登録する必要があります。

スクリーンショット 2020-09-26 23.37.22.png

今回は「DNSの検証」を選択します。
スクリーンショット 2020-09-26 23.37.29.png

「Route53でのレコードの作成」をクリックすると、ACMが自動でCNAMEのレコードを追加してくれます。

スクリーンショット 2020-09-26 23.38.03.png

検証に少し時間がかかるので、今のうちにALB用の証明書も発行しておきます。

状況が「発行済み」になれば完了です。
スクリーンショット 2020-09-27 3.03.33.png

Cloudfrontでカスタムドメイン(デフォルト以外のドメイン)を使用する場合はALBでのHTTPS化も必要です。
まずはALBのHTTPS化を行いましょう。

リスナーを「HTTPS」→「HTTPS」に変更します。

リスナーを選択して「編集」に進んで下さい。
スクリーンショット 2020-09-27 3.07.40.png

「プロトコル:ポート」→「HTTPS:443」に変更
「デフォルトのSSL証明書」から先ほど作成した証明書を選択をして下さい。

スクリーンショット 2020-09-27 3.07.58.png

次にCloudfront側でのHTTPS化を行います。

「Distribution」の設定から

設定 項目
Alternate Domain Names ドメイン名
SSL Certificate 先ほど作成したCloudfront用の証明書

を設定します。
スクリーンショット 2020-09-27 3.06.01.png

また、Behaviorの設定の

設定 項目
Viewer Protocol Policy Redirect HTTP to HTTPS

を設定することで、Cloudfront側でリダイレクトの設定を行うことができます。

補足
Cloudfrontを使わない場合はALBのリダイレクト機能を設定することで同じようなことができます。

スクリーンショット 2020-09-27 3.06.40.png

最後に、「Route53」にてレコードの追加を行えばHTTPS化の完成です。
スクリーンショット 2020-09-27 3.08.54.png

Route53

ヘルスチェックの有効化

Route53のヘルスチェックは3種類あります。

ヘルスチェックの種類
  • エンドポイントをモニタリングするヘルスチェック

    • IPアドレス OR ドメイン名 に対してTCP接続を確立しようと試み、正常かどうかを判断する。
  • 他のヘルスチェック (算出したヘルスチェック) を監視するヘルスチェック

    • 「エンドポイントをモニタリングするヘルスチェック」を複数使用し、AND、ORで制御可能なヘルスチェック
  • CloudWatch アラームをモニタリングするヘルスチェック

    • Cloudwatchを利用したヘルスチェック
    • ユースケースとしてはDynamoDBへのスロットル読み込みイベント数や正常に機能していると推測される ELBの数などの CloudWatch メトリクスのステータスをモニタリングして判断を行う みたいな使い方が出来ます。

フェイルオーバーを実装する為にヘルスチェックを関連付ける場合は基本的には「エンドポイント」で作成すればいいかと思います。

スクリーンショット 2020-09-27 3.44.08.png

SNS通知が利用できるので、Chatbotを利用して簡単にSlackBotも作れそうですね
これに関しては、後ほど作成を行います。
スクリーンショット 2020-09-27 3.44.19.png

Route53でのヘルスチェックでもレイテンシーも追加の設定で確認できますが、より詳しいサービスの監視を行いたい場合はCloudwatch Syntheticを利用するといいでしょう。

Cloudwatch Syntheticsを用いてサービス状況を監視

CloudwatchSyntheticsというサービスの概要は知っていましたが、触るのは今回が初めてでした。

設定はこんな感じでエンドポイントの URL を指定すると、その下の Canary Builder に監視内容を設定するコードが生成されるっぽいです。(現時点ではPythonは指定出来ない...)
スクリーンショット 2020-09-21 2.48.00.png

  • ハートビートのモニタリング
    URLをチェックしてくれる

  • API Canary
    そのまま APIバージョン

  • リンク切れチェッカー
    いろんなパスまで見てくれる

  • GUIワークフロービルダー
    ページ内での色々なアクションを監視してくれるっぽい
    スクリーンショット 2020-09-21 2.53.27.png

SNSトピックと関連付け出来るので、Slackへの通知も簡単そうですね

スクリーンショット 2020-09-21 2.48.25.png

ログと一緒にスクリーンショットも保存してくれるのは面白いです
スクリーンショット 2020-09-21 2.45.52.png

レスポンスタイムも
スクリーンショット 2020-09-21 2.46.14.png

ログも
スクリーンショット 2020-09-21 2.46.27.png

Cloudwatchアラームで異常時のアラートを設定する事もできます(レスポンスタイムでアラートなど)

Syntheticsの利点として一番大きいのは「圧倒的安さ!」かと思います。
1時間に1回実行する設定でもたったの約100円/月!!!

Datadogでもsyntheticsモニタリングありますけど、$12/月ですね。

また、AWS Lambda + Amazon S3 + Amazon CloudWatch Alarms を使ってるサービスなので、とてもわかりやすいです。それでいてとても柔軟な設定ができるので結構使えそうな気がします。

最後に

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