Q. Railsでdatabase.ymlを参照せずに外部に存在するWebAPIからDB接続情報を取得して db:create や db:migrate をしたい
A:
ぱっと思いつくのは
- database.yml内にAPIからDB情報を取得するコードをerb埋め込みで書く
- アプリケーションの外にAPIからDB情報を取得する部分を用意して環境変数DATABASE_URLに埋め込み
とかですかねー。Railsは環境変数DATABASE_URLが設定されてたらそこから情報を読むので
あんまりWebAPIに依存したくないので後者のほうが筋が良さそうだなとは思ってますが、WebAPIへのアクセス方法などで面倒だったり複雑な場合は前者ですかね…
Q:
database.ymlってerb埋め込めるんですね、知らなかったです。
マイグレーションの内容は顧客毎に差異があってはいけないのですが1回の db:migrate で全顧客のDBに反映することって可能でしょうか?
参考ページを読んでみたところ DATABASE_URL を設定したうえで db:migrate を実行しないといけないので複数顧客に対してマイグレーションを実行するとなると
顧客Aの情報を DATABASE_URL に設定して db:migrate 、顧客Bの情報を DATABASE_URL に設定して db:migarete を繰り返さないといけないのではないかと思いました。
B:
Rails 6から複数DB対応が入ったので、複数DBに対してマイグレーションすること自体はできる。
ただ、これは database.yml に全ての顧客のDB情報を入れる必要があるので動的にするのは難しそう。
A:
一応、erbでdatabase.ymlを動的に生成するようにすれば出来なくはないですが……
あと複数DB対応すると今の作りが1顧客に対して設定を変えたアプリケーションを起動するような構成になっている場合はアプリケーションロジックにも、どこのコネクションにestablishするか手を加えないとですねえ
C:
自分も erbでdatabase.ymlを動的に生成 がすぐに思い浮かびましたが、運用上あんまりうれしいやり方ではないですね
A:
ridgepole gemあたりを使ってRailsの外でmigrationを管理するっていう手もありそう
B:
自分なら顧客ごとにDB分ける仕様を変えるように動くだろうなぁ…。
まぁ、それが無理なら、自分なら以下のように頑張ると思う。
1. 顧客のDB名を customer_1, customer_2 のように連番にする
3. bin/rails db:migrate の前に顧客数を取得して、環境変数に設定
C:
この手の統合管理チックなことをやろうと思ったら、Railsとは違うレイヤで管理する必要が出てくるかなと自分も思います
B:
ただ、この方法でやるなら顧客が増えたときの制御は工夫しないと、スキーマずれちゃう可能性ある。
C:
サービスごとに管理するのが現実的に難しいのは(もちろん規模感にもよるけど)確実なので、もっと下回りで管理したくなるやつ
でもRails側と制御がかちあってしまうリスクもある
B:
あと、SmartHRさんがマルチテナントでスキーマ更新に1日かかって大変って話を以前にされていたので、そういうのも考慮がいる。
C:
大変そう
書き込みロックかかっちゃいそう
D:
マイグレーションにめちゃくちゃ時間がかかるのは容易に想像できますね
C:
データの構造や性質がわからないので何とも言えませんが、マスターデータとかであれば思い切ってDBごと切り出しちゃうとか 何なら別マイクロサービスにするとかもありえますね
A:
ずれてもいいように運用するっていう手もありそうな気はします
顧客ごとに別のエンドポイント用意して、更新は顧客ごとにatomicにするみたいな
B:
Ruby/Rails初学者向けのチャンネルだけど、マルチテナントという難しい話題なので、どうやっても説明が難しくなる。
C:
やろうとしてることの複雑性が高い・・・
E:
いつのまにか Microsoft に買収されていた
F:
マルチテナントやってたときはridgepoleでやってましたね。それでも適用に時間かかってやばかった
Q:
みなさんありがとうございます。
もともと私が携わる前にこういった土台が定義されていてフレームワークの仕様などを考慮していない状態だったので。。
そもそもの構造を変えることも可能ですがひとまずRailsだけで実現可能かな?と思った次第でした。
A:
いまの仕組みがあるならがっつりアプリケーション構造いじるのが難しい場合も多いので悩ましいですよねえ…
F:
共通テーブルがあるならそれの利用は最小限にして極力テナント内で完結するといいです
Railsでマルチテナンシーやってるの僕が知ってるなかだと3社さん
Q:
今の仕様だと共通テーブルはないですねぇ、それの代わりとなるのが質問で書かせてもらったWebAPIになるんだと思います。
マルチテナンシー、なかなかノウハウがないしあったとしてもウチの仕様とマッチしてなかったりで頭痛くなってきました…
まぁとりあえず理想とするところが技術的にもコスト的にも難しそうなので、そこひっくり返すところから始めようと思います みなさんありがとうございました!