あじちゃんのブログ。備忘録。

〜SEもOLなんですかね?

【解決】dump結果とview表示結果が異なる@Laravel 5.6

解決しました

参考リンク

解決方法

  • Modelに protected $casts = ['id' => 'string']; を追加したことで解決!!

解決までの道筋

  • dump結果とviewでの表示を見比べて、型がintegerになっているのではと推測

dump($items);
dump($items->last()->id);
echo $items->last()->id . '<br>';
return gettype($items->last()->id); // 型を返す

とかしてたら、「collectionで取得したものの型変換がおかしいんじゃない?」という気持ちになり検索

  • 検索ワードは「lalravel collection 型変換」
  • この記事を見つけてSUCCESS!!!

問題だったもの

  • モデルに定義したテーブルからとってきた値をビューに表示するだけなのに、表示結果がおかしい。
  • ModelクラスのtoStringを追うと、jsonEncodeするときに値がおかしくなっていることがわかるがそれが本当の原因かは不明。
+------------------+-------------+------+-----+---------+-------+
| Field            | Type        | Null | Key | Default | Extra |
+------------------+-------------+------+-----+---------+-------+
| id               | varchar(97) | NO   | PRI | NULL    |       |
+------------------+-------------+------+-----+---------+-------+
<?php

$query = ItemModel::query();
$items = $query
    ->orderBy('id', 'asc')
    ->get();

dump($items);
return view('test.index', ["items" => $items]);
<?php

@foreach($items as $item)
  <p>{{ $item->id }}</p>
@endforeach
<?php /* dump結果 */

"id" => "123--これはID--456"
// -> [123]が表示される
"id" => "test"
// -> [0]が表示される
"id" => "あいうえお"
// -> [0]が表示される
"id" => "3333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333"
// -> [9223372036854775807]が表示される

gitの複数のブランチを一括で削除する

xargs コマンドを使います。

xargs コマンドとは?

xargs コマンドとは、Linux のコマンドの1つ。
あるコマンドの出力を xargs コマンドに送り込み、別のコマンドの引数として指定することができます。

消したくない branch を除いた全ての branch を削除するとき

git branch | grep -v 消したくないbranch名など | xargs git branch -D

これは、パイプ( | )でくくった部分のコマンドを実行した結果に対して、 xargs 以降のコマンドを適用するという意味になります。 実際に実行したコマンドは以下の画像。(👹<s>-vが抜けてるのであとで書き直す 書き直した)

f:id:azix:20180816174516j:plain

git branch に対するコマンドは自分で判断してね。

【JavaScript】配列の比較について

まとめ

JavaScriptで、配列の比較の際に==又は===演算子を用いると、その配列が参照しているメモリ上のアドレスが同じかどうかでtrue/falseを返す。
Object.is() も同様。

var list_1 = ["mike","saba","tora"];
var list_2 = ["mike","saba","tora"];

console.log(list_1 === list_2);
// -> false
console.log(Object.is(list_1, list_2));
// -> false

配列が全く同じであっても、比較の際に == === Object.is() を用いると false が返る。
これは、比較対象が中の値ではなくポインタのアドレスを見ているため。

じゃあどうやって比較する?

一番楽なのは、toString() してしまう。 もしくは(冗長になってしまうけど)配列を回して比較。

var list_1 = ["mike","saba","tora"];
var list_2 = ["mike","saba","tora"];

console.log(list_1.toString() === list_2.toString());
// -> true
console.log(Object.is(list_1.toString(), list_2.toString()));
// -> true

ただ、Object.is()=== のようにオブジェクトを比較したいときはまたちょっと複雑そう・・・。いつか調べる。

追記

ツイッタで質問があったので。
JavaScriptの配列型にはequalsメソッドが存在しません。

[1, 2] == [1, 2];
// -> false

[1, 2].equals([1, 2]);
// -> Uncaught TypeError: [1,2].equals is not a function

外部キー制約 migration の foreigndrop がうまくいかない

(先に)まとめ

⭐️ 外部キー制約の drop と同時に、制約対象の key を変更や削除する場合はスキーマを分ける必要がある
✏️ 外部キー制約を drop するときは1つのスキーマでまとめて実行できる

テーブル条件

  • テーブル名:animals
  • カラム名:kindId
  • 外部キー設定先テーブル名:animal_kinds
  • 外部キー設定先カラム名:id

作成した migration ファイル

<?php

public function up()
{
    Schema::table('animals', function (Blueprint $table) {
        $table->unsignedBigInteger('kind')->change();
        $table->foreign('kind')->references('id')->on('animal_kinds');
    });
}

public function down()
{
    Schema::table('animals', function (Blueprint $table) {
        $table->dropForeign('animals_kind_foreign');
        $table->bigInteger('kindId')->change();
    })
}

migration を実行し、rollback した際にエラー発生

  [Illuminate\Database\QueryException]                                                                                   
  SQLSTATE[HY000]: General error: 1832 Cannot change column 'kind': used in a foreign key constraint 'animal_kinds' (SQL: ALTER TABLE animal_kinds CHANGE kind kind BIGINT NOT NULL COMMENT '-')                                                 
                                                                                                                         
  [Doctrine\DBAL\Driver\PDOException]                                                                                    
  SQLSTATE[HY000]: General error: 1832 Cannot change column 'kind': used in a foreign key constraint 'animal_kinds'                                                                                        
  [PDOException]                                                                                                         
  SQLSTATE[HY000]: General error: 1832 Cannot change column 'kind': used in a foreign key constraint 'animal_kinds'

down() を以下のように書き換えることで成功

<?php

public function down()
{
    Schema::table('animals', function (Blueprint $table) {
        $table->dropForeign('animals_kind_foreign');
    });
    Schema::table('animals', function (Blueprint $table) {
        $table->bigInteger('kindId')->change();
    });
}

【laravel】HasManyThrough() を使うときに規定通りに書いているにも関わらず結果が0件で困った

Eloquent:リレーション 5.4 Laravel 5.4公式サイトの表記

リレーションのクエリ実行時は、典型的なEloquentの外部キー規約が使用されます。リレーションのキーをカスタマイズしたい場合は、hasManyThroughメソッドの第3引数と、第4引数を指定してください。第3引数は仲介モデルの外部キー名、第4引数は最終的なモデルの外部キー名です。そして第5引数はローカルキーです。

Eloquent:リレーション 5.5 Laravel 5.5公式サイトの表記

リレーションのクエリ実行時は、典型的なEloquentの外部キー規約が使用されます。リレーションのキーをカスタマイズしたい場合は、hasManyThroughメソッドの第3引数と、第4引数を指定してください。第3引数は仲介モデルの外部キー名、第4引数は最終的なモデルの外部キー名です。第5引数はローカルキーで、第6引数は仲介モデルのローカルキーです。

しかしながら、この通りに実装しても全然値が取れない。
実はこれ、第6引数までとるみたい...

<?php

class First extends Model {
    public function Third()
    {
        return $this->hasManyThrough(
            'App\Third', 'App\Second',
            'C_id', 'A_id', null, 'B_id'
        );
    }
}

上記のような「FirstクラスからSecondクラスを経由してThirdクラスのデータを取得したい」場合、
hasManyThroughメソッドに渡す引数は順に、

  • 最終的にデータを取得するクラス(Third)...'App\Third'
  • 経由するクラス(Second)...'App\Second'
  • 経由するクラス(Second)と呼び出し元(First)を繋ぐキー...'C_id'
  • 呼び出し元(First)のマスターキー...'A_id'
  • よくわからないやつ👹 呼び出し元(First)のローカルキー...null
  • 経由するクラス(Second)と最終的にデータを取得するクラス(Third)を繋ぐキー...'B_id' となる。

5番目の「よく分からないやつ」「呼び出し元(First)のローカルキー」にはnullを渡すとうまくいった...これはいったいなんなのか???
これ、指定しなくてもいいんだねぇ......謎

😱💬 最初はこういう書き方してたせいで結果が0件だった.
    そりゃ経由するクラス(Second)と最終的にデータを取得するクラス(Third)を繋ぐキーがなければ結果が出るはずもないよね. 反省.

<?php

class First extends Model {
    public function Third()
    {
        return $this->hasManyThrough(
            'App\Third', 'App\Second',
            'C_id', 'A_id', 'B_id'
        );
    }
}

😭💬 教訓:ちゃんとバージョンにあったドキュメント読みましょうね.

【AWS】Laravelアプリケーションのデプロイ

Composer で作成されたファイルを含むソースバンドルを作成する

  • アプリケーションのルートで実行する
  • hoge.zip には付けたいファイル名を入れる zip ../hoge.zip -r * .[^.]* -x "vendor/*"

ソースバンドルをデプロイする

  • Elastic Beanstalk コンソールの管理ページへ移動する f:id:azix:20180722234450p:plain
  • アップロードとデプロイで先程のファイルを選択し、デプロイボタンを押下する f:id:azix:20180722235200p:plain 🦑 < 結構時間かかるよ

確認

  • ダッシュボードに遷移するので、完了になるまで待つ

ルートの設定

アプリケーションのURL叩くとエラーになってしまう。その原因は、ルートが / になっているから。
なので、ルートを /public にする必要がある。

  • Elastic Beanstalk コンソールの管理ページへ移動する
  • サイドメニューの [設定] へ移動する
  • [設定] の [ソフトウエア] から [変更] でページ移動する
  • [ドキュメントのルート] に [/public] と入力し [変更] で完了 f:id:azix:20180722235255p:plain

  • ダッシュボードに遷移するので、完了になるまで待つ
    🦑 < 結構時間かかるよ

CSVのデータを加工するときに使った関数の備忘録

改行とカンマで区切られたCSV文字列を想定し実施

f:id:azix:20180719203926p:plain

目的:与えられたCSV形式のデータから、頭2つのデータを配列として取り出す

  • こんな感じのフォームを準備
<form action="{{ action('よしなに') }}" method="よしなに">
    {{ csrf_field() }}
    <textarea name="csv" cols="30" rows="10" placeholder="CSV情報を入れてください"></textarea>
    <input type="submit" value="SEND">
    <pre>
例:
title-1, author-1, description-1
title-2, author-2, description-2
title-3, author-3, description-3
    </pre>
</form>
  • このフォームに例をそのままぶち込んで送信したものを加工する。
<?php

$csv = $request["csv"];

//改行ごとの配列
$item_groups = preg_split("/\n|\r\n|\r/", $csv);

//タイトルと著者の配列
$items = [];
$keys = ['title', 'author'];
foreach ($item_groups as $item_group) {
    $c = preg_split("/,/", $item_group); //カンマごとに配列に格納
    $chunk = array_chunk($c, 2)[0]; //前から2項目のみを配列に追加
    $changeKey = array_combine($keys, $chunk); //keyを変更
    array_push($items, $changeKey);
}

説明

  1. preg_split を使って、改行ごとに配列にする.
    正規表現\n|\r\n|\r で、改行コードを網羅.

  2. array_chunk を使って、目的のindexまでを取得し配列にする.
    これはindex[0][1]を取り出していると言うより、2個ずつ配列を分割している.
    今回はindex[0][1]が欲しかったので、2個ずつ取り出した初めの配列を使った.

  3. array_combine を使って、配列キーを変更する.

  4. array_push を使って、結果配列に追加していく.
    -array_push

🙂💬

特筆することはないけど、よく使う配列操作の関数は覚えておきたいなと思う.
あと、配列そのものに影響するのか、返り値が目的のものなのかというところも気をつけたい.