No Purpose

If I must say, it's for me.

Next.jsのチュートリアルをやってみて、"ホームページ" を作り始めてみた

Next.jsのチュートリアルを一通りやってみた。

nextjs.org

とても丁寧に作り込まれていて、chapterごとにクイズがあったり、読み進めると謎のポイントが溜まっていったりして、学習者を飽きさせないような工夫が凝らされていた。

また、Next自体もすごく便利そうな技術だなぁという感想を持ち、仕事で触っているCreate React App製のReactアプリとの比較なんかに思いを馳せたりした。まだそんなに確信は持てていないけど、CRAでなんか作ろうとするなら、代わりにcreate-next-appでなんか作ってもいいんじゃないかってことをまず検討してみてもよさそうだなと思った。

特にCRAが隠蔽していることを細かくチューニングしようとする気が(まずは)そんなにないんだったら、いっそのことNextに乗っかっちゃったほうがより便利になったりしないだろうか...?というのが僕の雑な初見での感想だ。 フロントエンドのアプリケーションを運用するようになってみて、npmを細かく分ける文化のためか、それなりにDependencyをチマチマと上げる作業がRubyやGoのプロダクトに比べて大変だなぁという思いがあって、routing機能とかlink先のprefetchとか画像のresizeとかreact-helmetにあたる機能とかが裏側で全部入りになってるようなNextは、(SSG/SSRを欲してなかったとしても)一つの選択肢になったりしないかなって思ったりした。

せっかくだし何か作るかと思って、自分のホームページを作り始めてみた。

f:id:highwide:20210507000514p:plain

https://highwide.net

まだ何もなくて、全然Next.js使う意味もないのだけど、意味もなく取ったままだったドメインに使いみちができて、なんだかうれしい。 何かコンテンツを増やしたいという気持ちはある。

コードはここに置いてある。

github.com

Vercelにデプロイするのは超簡単だったし、無料のままカスタムドメインの設定までできてありがたかった。

create-react-appで作ったアプリケーションはejectしなくても音を鳴らせる

タイトルのとおりなんだけれども...。

ejectしていないcreate-react-app製のアプリケーションで音声を鳴らしたくなって、調べたり聞いたことのメモ書き。 (というか、ほぼ5t111111さんに教えていただいたことを貼っているだけである...)

思考の変遷

  • あれ...音声を鳴らすためのmp3って普通にsrc/assets/に置いたうえで、importできるんだっけ...?
  • Webpackのbuild対象にするには、それ用のloaderが必要...?
  • ejectしていないアプリケーションってことはwebpack.config.jsを直接触れないけど、普通にaudioファイル扱える...?
  • とりあえずimport書いてみたけどエラー出てimportできないっぽいな
  • 雑にググったら「まずejectしよう」みたいな記事出てくるんだけど...?(若干古い記事が多い)
  • うーんでも、ここ見るとloadできそうなんだけどなぁ...。↓
            // This loader doesn't use a "test" so it will catch all modules
            // that fall through the other loaders.

from: https://github.com/facebook/create-react-app/blob/2d1829eaf6ff1308da00720fa9984620dd0fb296/packages/react-scripts/config/webpack.config.js#L583-L584

  • とかTwitterに書いてたら「普通に動く」っていう情報をいただいた

  • いただいたキャプチャを見てみると、global.d.tsで declare module "*.mp3"; としていることに気がついて、それについて聞いてみたことへの答え↓

  • ここで、file-loader通したbuildの対象にできてるかっていう話と、moduleのimportができるかという話を混同していてエラーを見ていたことのだとわかった。勉強になった。

というわけで、できた

github.com

↑ これは何かというと、会社のチームでモブプロするときにときどき使ってるツール(OSS化されている)「mobu」へのPR。 これまではドライバー交代のタイミングでブラウザのnotificationが出てきたのだけど、結構見落とすことが多いので、交代のときに音が鳴るようにしたかったのだ。 晴れてマージしてもらった。

ここで使えるよ→ https://mobu-waiwai.netlify.app/

ちなみに「mobu」を使ってモブプログラミングするときの話などは、同僚が会社ブログに書いている。

quipper.hatenablog.com

おわりに

たいした話じゃないかなぁって思いつつも...

  • "create-react-app mp3" とかでググるとejectしろみたいな記事が出てくるので書いてみた
  • global.d.tsの話は自分にとっては知見だったのでメモしておきたかった

という感じでした。

「UNIXという考え方」を読んだ

UNIXという考え方―その設計思想と哲学

UNIXという考え方―その設計思想と哲学

  • 作者:Mike Gancarz
  • 発売日: 2001/02/01
  • メディア: 単行本

モチベーション

  • 「ひとつのことをうまくやる」「小さいことはよいこと」「パイプでコマンドをつなぐ」といった、UNIX哲学とされるものはなんとなく聞きかじったことがあって、その哲学に心地よさを覚えながら名著とされる原典をスルーしているのはなんとなくの居心地の悪さがあったので読んでみた。
  • 年末年始にかけて業務が逼迫していてあんまり読書する心身の余裕がなく、先月末に無事リリースできて以降は大きく怠惰に振れていたので、リハビリがてら薄い本を読もうとした。

感想

その時代を知る読み物として

作中で登場するプログラミング言語アセンブリC言語シェルスクリプトで、本格志向のC言語ではなくてコンパイルがいらず移植性にも優れたシェルスクリプトを使おうといったことが繰り返し語られていた。

じゃあJavaはいつ頃登場するんだっけ...?と思って調べたらJDK 1.0は1996年1月だった: Java - Wikipedia

Windows 95登場前夜ながらも、Windows NTの時点でマーケティングに大成功していたのかなんてこともあまり知らなかった。

え、ちなみにLinuxは...?と思ったら、Linuxは「1997年ごろより商用目的への応用が注目され」という感じらしい: Linux - Wikipedia

...といった自分が知らなかった時代における、当時の人たちの"常識的"とされた考え方や「UNIXという考え方」がなぜ新しかったのかといった背景を知るのは結構おもしろかった。「クリーンアーキテクチャ」を読んだときにボブおじさんの昔ばなしもなんだかんだ言って楽しめたことを思い出した。感覚的には「スティーブズ」を読んでいるときに近い。

現役で通じる価値観を学ぶ読み物として

上述したような自分が知らなかった時代に書かれた"古典"ではありつつも、(よく言われているように)そこに書かれた価値観が現役で通じることに改めて驚いた。

「スモール・イズ・ビューティフル」「ひとつのことをうまくやらせる」「部分の総和は全体よりも大きい」といった価値観はマイクロサービスにも通ずるし、「効率よりも移植性」において重要視される移植性については現代ではコンテナという手段を得るに至ったんだなぁということを思い浮かべながら読むことができた。

「できるだけ早く試作を作成させる」については、(耳が痛い)言葉通りのことだけでなく、「人間には、三つのシステムしか作れない」という話がとても興味深かった。「三つのシステム」とは、特定の機能/領域が成熟するにつれて、それを担うシステムの変遷が起こるライフサイクルのような話だと理解している。

  1. 第一のシステムは、「追いつめられた人間」が作る。追いつめられているので「『正しく』やっている時間などない」。そのコンセプトは革新的なので「人間の想像力を刺激」する。
  2. 第二のシステムは、「第一のシステム」の成功に惹かれた専門家たちが作る。これまでの欠点を改善すべく「正しさ」を追求し「委員会」で設計する。結果、商業的な成功を納めることも多い一方で「ぜい肉がつき、遅い」「三つのうちで最悪のシステム」となる。
  3. 第三のシステムは、「第二のシステムで『火傷』した人が作る」。「ようやく『正しく』やることができる時間が与えられ」、「オリジナルのコンセプトはそのまま残り」、「第一のシステムと第二のシステムの最良の特徴を組み合わせる」。

ポイントは、どうすれば第三のシステムを作れるかというと「最初に他の二つのシステムを作るしかない」というのがおもしろい。だからこそ「できるだけ早く試作を作成させる」ということかと得心した。

そのうえで、僕はこれを読んで、以前の職場で関わった...

  1. 創業期に書かれた、「ひどい」と言わざるをえないがたしかに事業に売上をもたらしたコード
  2. 1を嫌った人たちが書いた、過度な抽象化(あるいは間違った抽象化)が施された結果、見通しが悪い(と感じる)コード
  3. それらを置き換えるべく、事業毀損しないようにポーティングしていくプロジェクトが発足

という流れを思い出した。 僕は3のプロジェクトに関わった。今振り返ると、あのとき作ったものが「第二のシステム」とみなされるべきものになってしまっている可能性は否定しないものの、少なくとも1と2については「第一のシステム」「第二のシステム」と称してよさそうに思う。

「3」から関わった身からすると「『1』において、もっと『正しく』作れなかったのか」「『2』において、もう少し現実的で適切な設計はなかったのだろうか」とついつい考えてしまうこともあったが、それ以上にこれらの「システム」が生まれてしまうこと自体は否定せず、そのライフサイクルのスピードをもっと上げられないか考えるというのがよりUNIX哲学的だったかもしれない...なんて振り返りを今さらした。

もっと早く読めばよかったという後悔

同僚はこの本を「はやく読めば読むほどお得な名著」と評していたが、その意味がようやくわかったようにも思う。

「ひとつのことをうまくやる」「小さいことはよいこと」などの哲学は、あまりにも普遍的になっていることで日常で触れる機会も多く、驚きはあまりなかった。

もっとこの本にガツンと頭を殴られ、UNIX哲学に麻疹のようにかかってしまう頃に触れておくべきだったという後悔を少ししつつ、今も色褪せぬ価値観のオリジン(と言っていいのかな)に触れられたことを嬉しく思う。

2020年個人的振り返り

今までこの手の振り返り記事はあまり書いたことなかったけど、今年はやってみようかなと大晦日の夕方に思い立って慌てて書いている。大きな変化があった年だが、淡々と個人的なことばかり書くつもり。

仕事

今年の10月で入社して1年になった。入社前に想像していたよりも悲しい別れが多い1年ではあったけど、それでもいい環境だなぁという気持ちは変わっておらず、継続して強い人の入社もあり、日々楽しく仕事をしている。

正直言って去年(つまり入社しての数ヶ月)はあまりバリューを出せた気がしないのだが、少しずつ仕事に慣れてきて、新しいことをキャッチアップしたり自分の強みを発揮したり...といったことが徐々にできるようになってきたように思う。(とはいえ今でも「このままじゃヤバい感」はある)

春以降、ほぼすべての業務を自宅からやるようになって、さすがに最初は集中できないとか、同僚とコミュニケーションを取るタイミングがわからず心寂しく思うとかあったけれど、だいぶ慣れてきた。

そんな中で、わかりやすく新しい技術にたくさん触れることができた。 graphql-rubyを利用したRailsをReact+TSのフロントから叩くような実装や、 モノリスRailsからGoによるマイクロサービス切り出しを行うような機会が得られた。

Goによるマイクロサービス切り出しはもっぱらプロジェクトが佳境の状態にあり、年末はそれなりに時間をかけて実装を行っていて、ややハードワーク感はあれど「夕食を食べながらさっきまで書いていたコードを幻視して、洗い物後、仕事に戻ってPull Requestを仕上げる」みたいなのは、そんなに嫌いじゃないんだなと思ったりした。(もちろん、自分の裁量でやっている/それを強要されない/チームに心理的安全がある/そういった期間の終わりが見えている...といった前提の上で)

仕事以外の技術の話

後半は家庭や仕事の状況の変化によりあまりできなかったが、知人のお手伝いでRailsを書いて、TerraformでAWSに構築して、マークアップを書くためにTailwindを触ってみたり...といったことをやれた。

あとは、5月頃に「りあクト!」の読書会をよちよち.rbの友人らとやったことが、自分のReact.jsの知識の定着につながったなぁという感覚がある。

また、「クリーンアーキテクチャ」や「マイクロサービスパターン」を読んでブログを書いたりといったことも、あんまりいままで自分がやってこなかったことなので、よい経験になった。(本当はもうちょっとブログ書きたいなぁって思ってたのに、前述の環境の変化で一気に習慣をなくしてしまった。この記事書いてるのはちょっとリハビリ感もある)

highwide.hatenablog.com

highwide.hatenablog.com

料理

前半はとにかくスパイスカレー作りにハマっていた。 今でも作るのは好きなんだけど、さすがに毎週作っていた今年の前半はなにかに取り憑かれていたなぁとか思う。

スパイスカレーを作る頻度が落ちたあとも、今年はいつになく自分でちょっとした料理を作ることが多かったなぁとは思う。リモートワークで自宅にいるし「妻が子供の離乳食を作って食べさせてくれているうちに自分たちの料理を作る」といった機会が多かった。

とはいってもそんなに大層なものを作るわけではなくて...

リュウジさんのバズレシピ を見て作ったり、

メスティンを買ってベランダで米を炊いたり、

インスタントラーメンをちょっと豪華にしたり、

フードロスになりそうな食材を買ってやりたい放題したり、

...といった感じだった。

子育て

昨年末に生まれた第一子の息子が1歳になった。毎月の月齢フォトを撮っていたのだが、見返すとやはり感慨深い。

子育てをしてみて驚くことはたくさんあるけれど、何よりも驚くのは「子供って何かが突然できるようになるんだな」ということ。 昨日まで寝返りができなかった、つかまり立ちができなかった、いただきますができなかった...そんな子供が突然今日できるようになる。誰かから手取り足取りやり方を教わったわけではないのに...というのがおもしろい。

また、リモートワークしていることで、そういった「何かができる」瞬間にたくさん立ち会えたことがうれしかった。

f:id:highwide:20201219181104j:plain
台所に入らないよう置いたウォーターサーバーの水につかまって調理を監視する様子

写真

そりゃそうだけど、近所で撮った写真が多かった。

f:id:highwide:20200329110711j:plainf:id:highwide:20201018172439j:plain

人様に迷惑かけないようにしつつペルセウス座流星群を強行軍で撮影に行けたのはよかったな。

f:id:highwide:20200812192744j:plain

f:id:highwide:20200812233744j:plain

反面、天気を理由にネオワイズ彗星を諦めてしまったのは本当に心残り。

レンズは以下の3本を買った(買ってしまった)

来年のこと

世の中が落ち着くことを心から願いつつ、妻の復職や子供の保育園入園(させてくれ...頼む...)といった大きな環境の変化を乗り越えて、家族の健康と自身の成長のために行動していきたい。

「マイクロサービスパターン」を読んだ

この本を読むまでの経緯

  • クリーンアーキテクチャを読んだ記事でも書いたように、仕事でマイクロサービスの導入検討(どの粒度でサービス化するか、など)を行っていて、自分があまりにも「Railsモノリスを作る」以外の選択肢について疎いと感じていた
  • これまた前のエントリにも書いたが、そんな中で上司の id:gohan_pan_gohan (何このはてなid....)もこの本を最近読んでいる旨を1on1にて話してくれて、自分も読むことにした
  • 一方で「クリーンアーキテクチャ」に書かれているような内容が前提となることも聞いていたので、先にクリーンアーキテクチャを読んでいた

この本について

  • 原著は「Microservices Patterns: With examples in Java」のタイトルで2018/11/27に出版されていて、日本語版は2020/3/23に出版された
  • 著者のサイトである https://microservices.io/ を基にしながら、架空のフードデリバリーサービス( Uber Eatsっぽい感じ)の設計/実装を検討してくいく
  • 「マイクロサービスにおける○○」がひたらすらの500ページ超のボリュームで語られていて、マイクロサービス設計/実装における勘所を体系的に学べる

感想

いま見返すと「理解できる」(理解できるとは言ってない)くらいに捉えてもらったほうがよさそうではある(逃げ腰)

ただ、本当に笑っちゃうくらい知らないことが多かった。

たとえば: サーガについて

モノリスで実現できていたRDBMSトランザクションをどうやってサービス分割後に担保するかというのは、読む前からの気になりどころだったのだが、これに対しては「サーガ」というテクニックが紹介される。(余談:redux-sagaのsagaってそういうこと...?)

サーガは、1つのトランザクションでやりたかった処理が複数のサービスに散らばってしまった場合に、サービスごとのトランザクションを1つの「サーガ」という風に捉え、仮に個々の処理が失敗した場合は個々のサービスで「補償トランザクション」を実行することでロールバックするような仕組みと理解している。このとき、これらの個々のトランザクションをコーディネイトする責務をどこに持たせるかによって「コレオグラフィ」と「オーケストレーション」という2種類の作り方ができる。ただし、サーガはACID特性のうちIsolation(分離性)はサポートできないので、Lockなどの対処手法(countermeasure)を用いていく必要がある。

microservices.io

...と、やろうとしていることは理解できる(というか、わりと泥臭くやらなきゃいけないんだなという思いを新たにする)のだけれども、聞き馴染みのないキーワードによってそのパターンが既に一般化されていることを知る...というのがこの本で学べるおもしろさだった。

たとえば: Transaction log tailingパターンについて

非同期メッセージングやその一種であるPubSub自体は業務でも使われているシーンを見ていたり、その概念を理解しているつもりだったが、Transaction log tailingパターンというものには驚いた。

この技術が解決したい問題は以下のようなものだ

  • メッセージのPublisherは「メッセージのPublishと、そのサービスのためのデータ保存とを、1つのTransactionの中で行いたい」(=メッセージ送信とDBの保存の部分成功/失敗を許容したくない)ケースがある
  • そのために、メッセージキューとしてDBに作成した「OUTBOX」というTABLEを利用することで、キューの更新とドメインモデルの保存をRDBMSトランザクションの中で行える、とうTransactional outboxパターン*1というものが存在する
  • このパターンを利用した場合、メッセージブローカーへのパブリッシュ自体は、OUTBOXテーブルの情報を取得するコンポーネントが必要になる
  • シンプルにやるならばOUTBOXテーブルにSELECTクエリでポーリングするコンポーネントを用意すればいいが、場合によってはDBへのポーリングするコストが無視できないことがある
  • そこで、RDBMSが吐くトランザクションログ(コミットログ)をテーリングして、変更を検知し、メッセージブローカーへのパブリッシュを行う

https://microservices.io/i/patterns/data/TransactionLogMining.png

画像は micorservices.io - transaction-log-tailing より

僕の直感からすると「ログ収集とかそういうレベルでなく、アプリケーションがRDMBSの吐くログに直接依存している...って大丈夫!?」って思ったりもしたのだが、世の中にはそれを実現するためのDebeziumLinkedIn Databusといったツールが存在していることも紹介されている。

さらにこの技術と相性がいいのが「CQRS」であると紹介されていて「えっCQRSってこの文脈で出てくるの?」といった驚きもあった。

「マイクロサービス」と「分散システム」

正直に言うと、上に挙げた技術やその他本書で紹介されているテクニックは、自分の日常業務にすぐさま取り入れたいと思う類のものだけでなく「そこまでやるの?」と感じるようなものも少なくない。

ただ、これまで「マイクロサービス」という言葉を日常的に口にする中であんまり意識していなかったことだが、本書を通じて「Microservices」とは結局「分散システム」なのだということを肌身に感じることができた。「自分たちのWebサービスのためのマイクロサービスではそこまではやらなくていいでしょ」とコストパフォーマンスの天秤を眺めている傍らで、高度な分散システムに続く道のりが続いていることを意識できたのは、すごく良かったと思う。

その上で、この本のスタンスも「はじめに」で書かれている通り

本書はマイクロサービス宣言ではありません。本書は、パターンのコレクションを中心として構成されています。(中略)パターンのよいところは、ソリューションの利点を説明するだけでなく、ソリューションの欠点やソリューションをうまく実装するために対処しなければならない問題点なども明らかにするところです。

とあるように、読み手に「分散システム全部盛り」をいついかなるときも要求するものではない。

自分の当初のモチベーションを満たす上でも、現実の業務に当てはめるためのパターンを「API合成」「テスト」「デプロイ」「セキュリティ」等々の面から学ぶ事ができた。GraphQLやKubernetes/Istioといった業務に直結しそうな技術の詳細な紹介もあったりして、マイクロサービス時代のWebアプリケーション開発を総ざらいできる本、とも言うことができるかもしれない。

その他の雑感

  • サンプルコードがJavaで、著者の自作フレームワークが登場しがちなので、せっかくの実装例は目が滑りがちだった...。いざ自分が実装するときには読み返すことになるかもしれない。
  • 日本語版の出版は2020年だが、原著は2018年なので、紹介されているツールは既に別の技術に取って代われられているように思えることもあった。「マイクロサービス時代のWebアプリケーション開発を総ざらい」と上で書いたが、賞味期限が短い箇所もそれなりに多そう。
  • 各パートごとに紹介されるツールのNetflix率の高さよ...。よく知られるchaosmonkyが"壊してまわる"のは、こんな分散システムだったのかなという思いを馳せた。
  • (思い出して追記) クリーンアーキテクチャを先に読んでたおかげで、こういう学びもあってうれしかった

仕事部屋の二酸化炭素濃度をRaspberry Piで測定するようにした

勤務先はこれまで「出社推奨」というスタンスだったが、コロナ禍になってからは徐々にリモートワーク前提の文化/制度/オフィスの設計がなされるようになり、3月頃からはほとんどの業務を自宅で行っている。 *1

昨年の10月に「子供が生まれる前に、お互いの実家により近くなり、間取りも広くなるような引っ越しをしよう」と決めて今の賃貸マンションを選んだ結果、幸いにも今は仕事部屋にあてがうことができる部屋が一室あり、僕はもっぱら平日の日中をそこで過ごしている。 (去年の秋にはこんなに自宅で業務をすることになるとは思っていなかったので、本当に僥倖だった...)

さて、そんな仕事部屋(かっこいいという理由で「書斎」と呼んでいるので、以後そう表記する)の環境についての話。

8月が終わってだんだん涼しくなってきたので日中クーラーを切ることが増えてきた。 書斎の窓はマンションの通路と面しているので、ミーティング等で発話するようなタイミングでは窓を開けておくことがはばかられる。 そのうえで、最近のチームの働き方としてオンラインでのモブプログラミングをすることが頻繁にある。 ...というわけで、必然的に「クーラーをつけていない × 部屋を閉めきっている」という状況が増えてきた。

その結果がこれ。

なんでいきなり二酸化炭素濃度に当たりをつけているかというと、こういう記事もあるし、

news.yahoo.co.jp

前職のオフィスにおいてもそんなことが問題になっていて、Netatomoで計測して、Redashで可視化するということをやっていた人がいたから。

上の記事にもあったけど、厚生労働省によると「二酸化炭素の含有率」は「100万分の1000以下(=1000 ppm以下)」を基準としている。

www.mhlw.go.jp

というわけで、室内の二酸化炭素濃度を可視化して換気を促すような仕組みを導入したい〜〜と思って二酸化炭素濃度モニターを調べてみたのだけれども...

  • IoT的な仕組みがない
    • つまり、計測値を自分で都度目視しなければいけない
    • 「やべぇ...息苦しい...そういえば、二酸化炭素濃度は...?ウッ、この濃度なら30分前に換気すべきだった...」となりたくない
    • というわけで閾値を超えたら通知を送ってほしい
  • 思ってたよりも結構お高い
    • Netatomoは25,000円程度
    • 単純な計器でも10,000円以上することがざら

といった感じでで、どうしたものか悩んでいた。

そこで、自宅で転がっていたRaspberry Pi 2を利用できないか考えてググったところ、先人たちの知恵が見つかった。

dev.classmethod.jp

qiita.com

mh-z19というセンサーをRaspberry Piに接続することで二酸化炭素濃度が取れそうだとわかる。センサーはAmazonで3000円程度、ということでポチッ。

ただ、センサーが届いてみて、あれ?これRaspberry Pi接続するのに他の部品が必要なのでは...?とジャンパーケーブルやらピンヘッダーやらを買い足したうえ、最終的にはんだ付けしないといけないことに気がついて、はんだ付けキット一式までを買ってしまった😇*2

そもそも名前がわからないと買えない、の図↓*3

で、なんとか接続がうまくいって、先ほどのQiitaの記事の方が作ったpipを利用してco2濃度が取得できるところまでできた、図↓

最終的に、厚労省が基準にしている1000ppmを超えたら、家庭用のSlackに通知がいくようにしたかったのでちょっとしたスクリプトを書いた。

github.com

ただまぁ、パブリックなコードにしたものの、これが本当に人様に見せられるようなコードではなく、最低なんだよな...という図↓

とはいえ、無事に閾値を超えたらSlack通知がされる仕組みは整えることができた。やったー!

f:id:highwide:20200914153655j:plain
とりあえず今はセンサーがむき出し

f:id:highwide:20200913180801p:plain

*1:ちなみにチームの人が、リモートワーク中の働き方の様子を会社のブログに書いてくれている。

リモート環境でも同じように楽しくやりたい!(前編) 〜2020年度Coaching チームのリモートふん闘記〜 - Quipper Product Team Blog

リモート環境でも同じように楽しくやりたい!(後編) 〜2020年度 Coaching チームのモブプログラミング、オンボーディング事情 〜 - Quipper Product Team Blog

*2:以前自作キーボードを作ったときは、前職の同僚にはんだ付けキット一式借りた

*3:画像は上に挙げたクラスメソッドさんのブログから

RailsのmigrationでPostgreSQLのenumを使おうとするとschema.rbが生成できない

タイトルのとおりなのだけど、仕事でちょっとハマった話。

特定3種類の値だけを利用するフィールドを追加したくて、Railsenumは使いつつ、DB上でもenumで型定義しておけば"固い"よなと思って、そういうテーブル定義をしようとした。 このあたりは前職のMySQLのテーブル定義においてそういうカラムがよくあったので、まぁポスグレでもできるだろうという感覚で調べ始めた。

軽く調べてみると、以下のような記事(翻訳もあった)があったり、

naturaily.com

RailsGuidesにも「Active Record と PostgreSQL」のページに「1.7 列挙型(enumrated type)」の記載があった。

railsguides.jp

enumの型定義自体は create_table などのDSLの中でできず、

execute <<-SQL
  CREATE TYPE article_status AS ENUM ('draft', 'published');
SQL

と、SQLを直接実行しているが、これがよく行われているやり方なのかなと理解した。

自分もそのように書いてみて db:migratedb:rollback が問題なく実行できることを確認したのだが、あとからschema.rbに以下のようなメッセージが生成されていることに気がついた。

# Could not dump table #{TABLE名} because of following StandardError
#   Unknown type #{enum用に定義したtype名} for column #{enumを使いたかったカラム名}

というわけで、上に書いたようにRubyDSLでPostgresのenumが定義できないために、schema.rbも生成できないと理解した。

あとから気づいたが、close済のissueもあった。

github.com

schema.rb can't support a few database specific constructions. You need to change the format to sql if you want to use those features.

とのことで、schema.rbでなくstructure.sqlを利用するようにしてあげれば、こういったmigration用のDSLで表現できないTABLE定義も利用できそうだ。 もしstrucuture.sqlを生成したいのであれば、config.active_record.schema_format:ruby ではなく :sql に変更すればよい。

railsguides.jp

ただし言わずもがな、ActiveRecordの抽象をひっぺがして特定RDBMSへの依存を高めることにはなるので、プロジェクトでの利害は考えた方がよいと思う。