ぷっぽプログラミング備忘録

linux, javascript, php, C#, そのうちScalaとかアプリ開発とかやってみたいです。

Laravel collectionのkeyBy()メソッドで、pluck()と似たようなことができる

概要

Laravelで、DBテーブルの取得結果を、特定のカラムをキーとして取得したい場合、調べるとpluck()がよくでてくる。 ただ、KeyBy()でもできる。 QueryBuilderなどではget()などでいったん取得してきておいて、後から加工するほうがいいケースもありそうなので記載。

公式そのままです…

$collection = collect([
    ['product_id' => 'prod-100', 'name' => 'Desk'],
    ['product_id' => 'prod-200', 'name' => 'Chair'],
]);
 
$keyed = $collection->keyBy('product_id');
 
$keyed->all();
 
/*
    [
        'prod-100' => ['product_id' => 'prod-100', 'name' => 'Desk'],
        'prod-200' => ['product_id' => 'prod-200', 'name' => 'Chair'],
    ]
*/

keyByメソッドは指定したキーをコレクションのキーにします。複数のアイテムが同じキーを持っている場合、新しいコレクションには最後のアイテムが含まれます。

参考

Collections - Laravel - The PHP Framework For Web Artisans

postgresqlでmysqlのgroup_concatと同じことがしたいならstring_aggを使う

前提

postgresql バージョン9以上ぐらい?

結論

string_agg を使う

例)barテーブルのtype_idでgroup byしたときに、foo_nameカラムをカンマでひとまとめの文字列にする

SELECT
    bar.type_id,
    string_agg(bar.foo_name, ‘, ‘) as foo_name_list
FROM
    bar
GROUP BY
    bar.type_id

参考

Postgres GROUP_CONCAT (Example)

vite + phaser + htmlのdomを使う

前提

  • viteでコンパイルしている
  • phaser3で何か作っている
  • phaesr3でhtmlのdomを使いたい

流れ

  • start-dom-jsx をインストール
    (dom-jsx単体をインストールして設定をすればできるようですが、簡単そうなので、start-dom-jsxのほうを私は使うことにしました。)
npm install start-dom-jsx
  • vite.config.js を更新
// 省略
    esbuild: {
        jsxFactory: 'h',
        jsxFragment: 'Fragment'
    },
// 省略
  • jsx ファイル作成(例button.jsx)
    ポイント:使っているようには見えないが、import {h, Fragment} from ... の一行を書くこと
import { h, Fragment } from 'start-dom-jsx'

const button = (
    <button class="button is-primary">
        <span class="icon">
            <i class="mdi mdi-play"></i>
        </span>
        <span>
            Start!!!!!
        </span>
    </button>
)

export default button
  • phaserのgameconfigに以下を追加
const config: Phaser.Types.Core.GameConfig = {
  // 省略
  parent: 'phaser', // ★これが必要★
  // ★以下が必要★
  dom: {
    createContainer: true
  },
  scene: MyDialog, // 例)MyDialogがシーンクラス名だった場合
};
new Phaser.Game(config);
  • phaserのsceneでjsxを使う
    例)MyDialog.ts
import Phaser from "phaser";
import button from "../jsx/button" // 使いたいjsxの部品ファイルのパス

export default class MyDialog extends Phaser.Scene {
  create() {
    this.add.dom(100, 100, button) // x:100, y:100 の位置にbutton.jsxのdomを表示させる 
    // buttonのclickイベント設定
    button.addEventListener('click', () => {
      // 適当に四角出してみる
      let graphics = this.add.graphics()
      graphics.fillStyle(0x800000, 1).fillRect(10, 10, 100, 100)
    })

  }

}
 

参考

Use Vite for JSX without React. If you want to build vanilla JavaScript… | by David Mold | Medium

DOM Element Button in Phaser 3 with JSX and TypeScript @ Playful Game Developmet Blog by Ourcade

Laravelのクエリービルダー(query builder)でLATERALを使う場合

DB::table('foo as f')
->leftJoin(
   DB::raw("
          LATERAL ( 
            SELECT
               MIN(goods.amount) as min_amount 
            FROM
               goods
            WHERE
                foo.goods_id = goods_id
         ) as temp_min_amount
   "),
   DB::raw('1'),
   '=',
   DB::raw('1')
)
->select('f.*', 'temp_min_amount.min_amount )
->get();

ポイント

  • DB::rawを使う
  • ON句が不要の場合は、SQL的には ON 1 = 1 とか ON TRUE とかにしたいのだが、laravel的には ON 1 = 1 一択っぽい。ただし、 1=1 するためには、DB::raw('1') = DB::raw('1')としないといけない

heroku + Laravel で外部サーバー上にあるデータベースに接続する

結論

herokuはデプロイが独特ですが、中身は普通のサーバーなので、 Laravelのconfigのdatabase部分に、データベースの設定をすれば動きました。 ただし、ご存知のように、herokuのLaravelの設定は.envに書いても意味ありませんので…。

heroku config:set DB_CONNECTION=mysql
heroku config:set DB_HOST=ccccc
heroku config:set DB_DATABASE=ddddd
heroku config:set DB_USERNAME=aaaaa
heroku config:set DB_PASSWORD=bbbbb

みたく地道にconfig:setでherokuに環境変数を設定していく必要はあります。

heroku上のLaravelの設定の確認

まずtinker起動。

heroku run php artisan tinker
config('database.default');

でdatabaseのドライバーの確認。 mysqlpgsql とかでるはずです。この文字列をdatabase.connectionsの後ろにつけて

config('database.connections.pgsql');

と実行すると、Laravelのデータベースの設定がでますので、

> config('database.connections.pgsql');
= [
    "driver" => "pgsql",
    "url" => null,
    "host" => "123.123.123.12などのipか、hogehoge.comみたいなhost名か",
    "port" => "5432とかのポート番号",
    "database" => "データベース名",
    "username" => "postgresのユーザー名",
    "password" => "パスワード",
    "charset" => "utf8",
    "prefix" => "",
    "prefix_indexes" => true,
    "search_path" => "public",
    "sslmode" => "prefer",
  ]

とかでるので、そこで確認できます。

参考

(Laravel)(MySQL)herokuでmigrateできない。

HerokuにLaravelで作ったアプリをデプロイする方法(MySQL編) - Qiita

postgresql jsonbの一部を更新する

方法

jsonb_setを使います。

fooテーブルのidが55 のデータに対し、 jsonb型カラムjsn_clmnの中身が {"a":{ "b": "bar"} だったものを {"a":{ "b": "nyaa"} に変える

UPDATE
    foo
SET
    jsn_clmn = jsonb_set(jsn_clmn, '{a,b}', '"nyaa"')
WHERE
    id = 55
;    

参考

9.15. JSON関数と演算子

herokuのconfigをまとめて設定する

Laravelの環境設定は.envで行います。 herokuには.envはpushできません。(.gitignoreで指定されているため) 方法は、

heroku config:set APP_DEBUG=false

といった感じで、config:setで、.envに記載されたLaravelの環境変数を登録していく必要があります。

一括で登録するには、

heroku config:set $(cat .env)

とすれば.envの内容がherokuに一気に登録されます。

※実際には、.env.productionとかに定義して、

heroku config:set $(cat .env.production)

とかになるでしょう。.envはlocalでの開発に使う人も多いので。

参考

heroku の環境変数をまとめてセットしたり削除したり | NizLog