Railsを使う上でのベストプラクティス

清野隼史氏(以下、清野):テーマ3でいろいろなあるあるを聞けたので、テーマ4「これからRailsとどう向き合っていくといいのか」に行きます。先ほどの話にもあった、Railsはこうなってきている。いいところもあるし、つらいところもある。さらに、今Webアプリケーションの現場はこうなってきているという話があった。その上で、今から僕たちはRailsとどう向き合っていくといいのかを、締めとして話そうと思います。

最初に、アドバイス的にうかがいます。最初にRailsを使う上でのおすすめめのベストプラクティス。「こう使っていくといいよ」ということはいかがでしょうか?

櫻庭洋之氏(以下、櫻庭):これは定番ですが、Rails Wayに乗って極力シンプルに保つということが1つ。Rails Wayではあるけれど、個人的にはモデルのコールバックは極力使わないようにしています。コントローラーというか、操作する側で愚直にロジックをきちんと書いたほうが(いい)。

マジカルな処理によって意図しない不具合が起きたり、テストを書く時にコールバックをスキップしたりしをいちいちやらなければいけなくなるので、Railsの便利さには乗っかりつつ、すべてのRailsの機能を使う必要はないと思います。

清野:ちなみに今の話にあった「この機能はあまり使わないほうがよさそう」とか、「控えたほうがよさそう」という機能をうかがえますか?

櫻庭:先ほど言ったモデルのコールバックなので、after_commitあたりは使わない。ほかにはConcernでとりあえず分割するだけの状態は意味がないので避けたほうがいい。それくらいかな。

清野:まさに今のcommit系とConcern系は破滅を生み出すというか、参照に飛べなくなる。少なくとも書いてあるコードが読める状態を作ることが大事でしょうか?

櫻庭:そうですね。

清野:赤沼さんはいかがでしょうか?

赤沼寛明氏(以下、赤沼):同じ回答になりますが、とにかくレールから外れないのが大原則です。やりたくなる時もあるとは思いますが、グッとこらえてレールに乗っかっておいてもらうのが一番重要だと。

ほかには、Railsがもともと持っている仕組み以外の黒魔術は極力作り込まないようにする。これは今、櫻庭さんが言ったことと同じだと思うので、その上でRailsが向かないと思ったらRailsではないものを使うのも1つの手かと。無理やりRailsを使おうとしないと言うと元も子もないのかもしれませんが、重要な気はします。

1人で開発していて使うのならいいと思いますが、チームで開発するのであれば、ある程度方針をそろえておく。基本的にServiceクラスは使わないほうがいいと思いますが、使うのであれば、きちんと使い方を決めておかないといけない。それぞれ好き勝手に作り始めると収拾がつかなくなる。そのあたりの方針をチームの中でそろえた上で使うことが重要で、その上でバージョンもこまめに上げていくといい気はします。

清野:レールから外れるようなことをするのであれば、外れているなりに自分たちでレールを敷き直すというか、合意を作っていくということでしょうか。

赤沼:いつの間にか誰かがレールから外れちゃっていると、誰も知らないまま進んで(笑)。

清野:ただ脱線しているだけという(笑)。

赤沼:まさに。

清野:あるあるですね。

櫻庭:そういう意味では、みなさん入れていると思いますが「RuboCop」は絶対入れたほうがいいです。rubocop-railsでメッチャ教えてくれるので。

清野:RuboCopもそうだし、テスト周りをしっかり作っていくことがRailsではほぼマストですよね。型があったりするので。「確かに、Railsの中でも自分たちで何を選ぶかが大事な時、変化についていけないものがありますよね」というコメントが来ています。Webpackerはretiredとされていたり、フロントエンド周りではRailsも迷いながらやっていることがあるのでしょうか。

櫻庭:DHH(David Heinemeier Hansson)のフロント周りのセンスが出てくる。

清野:そうですね。

赤沼:新しく機能追加されたからと飛びついてしまうと、早く消される可能性がある気はします。

清野:まさに。「自分も昔はConcernsで分割していましたが、見とおしが悪くなるので最近は冗長でも各モデルに書くようにしています」というコメントが来ています。続いて「逆にConcernを使うといいケースを教えてください」という質問が来ています。あるんですかね?

櫻庭:難しいですね。正直、僕が過去書いた中で、Concernでうまくフィットしたものはありませんでした。DHHが推奨するものや動画で上がっているものを見ながら模索していた時期もありますが、取り扱いが難しいというのが、今の僕の中で結論になっています。

清野:なくても作れるので、いったん触らないほうがいいということでしょうか。

櫻庭:そうですね。

RBSの機能をRailsでどう活用していけばいいか?

清野:話変わって、先ほどRubyの型的なRBSの話もありましたが、RBSの機能をRailsでどう活用していけばいいですか? まさにこれからというところだと思いますが。

櫻庭:僕が試した限り、まだ発展途上という感じなので、どちらかというと使ってフィードバックして成熟させていく活動がすごく重要だと思っています。単純に使いたいだけの人だと、現段階ではメチャクチャうれしいところまではまだいっていない感じがしました。

清野:これからのためにやっていく程度のものということですね。

櫻庭:そうですね。今見ているみなさんにもRBSに触ってもらって、たくさんフィードバックを上げてもらえると、みんな幸せになると思う。

清野:赤沼さんはいかがでしょう?

赤沼:私はあまりそこに触れていませんが、型が使えるからといって静的な型付け言語と同じようなことができるわけではないと思っています。試せるものは試してみたらいいんだろうなと。確かRuby自体、まつもとさん(まつもとゆきひろ氏)自身も静的な型チェックを推進していく感じではなかった気がするので、今後どうなるかはもう見てみないとわからない。

清野:今はどちらかというと、ウォッチするフェーズということですね。

赤沼:そうですね。本当に役立ちそうならすぐ使えるようにしておくのがいいのかなと。

Rails7の機能を「こう使う」

清野:続いて、先ほどの最近新しいものが出てきているとか、Railsも新しい試みをしているという話題の中で、一番新しい試みを行っているバージョンはRails7だと思います。Rails7の機能について「こう使う」ということがあれば、ぜひうかがいたい。

櫻庭:僕はRails7のすべてを把握はしていませんが、やはり一番はフロント周りのエコシステムが大きく変わったことです。Rails7に限りませんが、フロント周りがRailsが考えるフロントエンドのかたちの1つの回答になると思います。先ほどWebpackerの話がありましたが、そうは言っても今のHotwireをすぐに降ろすことはないと思っているので、そこを信じて採用するか、もしくはReactのほうに行くのかが1つの大きな分岐点になるという感じです。

Railsを使っている中で、ReactやVueを使うときに気をつけること

清野:ちょうどまたReactの話があったので、それについてもうかがいます。現時点ですでにRailsを使って開発をしている会社は、どうしてもReactを触らざるを得ないフェーズになっていると思います。そんな中、Railsを使っている前提でReactやVueを使う場合、「少なくともこういう構成にすべき」とか、「こういうことを考えたほうがいい」という点があればぜひうかがいたい。いかがでしょうか?

櫻庭:最低限というか、GraphQLは絶対に入れたほうがいい。TypeScriptで書く時のうまみをREST APIで書いた時の型情報が抜け落ちた状態でやり取りするのはしんどいと思うので、それがいいのではないかと。

清野:先ほどの話にあった、バックエンドとフロントエンドのインターフェースを統一させていくということは、少なくともやっておいたほうがいいということでしょうか。

櫻庭:そうですね。

清野:赤沼さんはいかがでしょう? ユニファで取り組んでいることがあれば、ぜひうかがいたいです。

赤沼:弊社はフロントエンドをRESTのAPIでやっています。メンバーにあらためて「REST APIでつらいところある?」とか「GraphQLを入れたい?」とか聞いてみましたが、意外と今のメンバーはRESTで困ることはないという反応でした。

ドキュメンテーションでAPIの仕様をアップデートしていく時は、最初はいいけれど、ある程度きちんとメンテナンスしなきゃいけない煩わしさがあるくらい。そのあたりは、GraphQLであればインターフェース定義がそのままドキュメントに落とし込めると思うので解消できるかと。

現状では、意外とみんなRESTで大丈夫そうだった。個人的な興味としてはGraphQLを試そうと思っていますが、チームとしては今すぐ取り入れる感じではありませんでした。

清野:そうなんですね。そもそもREST自体しっかり規約にのっとって書けるのであれば、それで耐えられるものだと思うので、そういう点をしっかりやっていくのも大事ということでしょうか。

赤沼:そうですね。少なくとも内製だけでやっている分には、さほど問題にならないという気はしました。ただ、フロント周りを外部のベンダーの方に委託するとなると微妙かなと想像しています。

清野:現時点では問題なく進められているということですね。

赤沼:そうですね。

GraphQL Rubyでスキーマ駆動をするときのベストプラクティス

清野:「RailsでGraphQLを使うと『GraphQL Ruby』になると思いますが、GraphQL Ruby自体はコードファーストになっていて。スキーマ駆動をやろうとするなら何かいい方法はありますか?」という質問が来ています。

櫻庭:僕もベストプラクティスを知りたいですね(笑)。

清野:そうですよね(笑)。GraphQLの魅力はコードで書いたものがスキーマになっていくことで、どちらかというと逆だと思うので。スキーマファーストだと逆にOpenAPIとか?。

櫻庭:OpenAPIでRESTで書いていくほうが向いている気がします。

Railsに期待していること

清野:1時間まるまる使って、Railsってこういうところがイケてる、こういうところがイケてない、今後こういうふうに向き合っていくといいという話ができたと思います。最後にまとめとして一言、Railsに期待していることや、こう使っていけたらいいなと思っていることがあればうかがいます。櫻庭さん、お願いします。

櫻庭:本当にRailsは開発速度がすごく早い、いいフレームワークだと思っているので、それを担保しつつ順当に進化してくれるといい。また、フロントエンドの昨今の要求を含めて、DHHなりの1つの解を出してくれていると思うので、それをベースに、世の中でよりディスカッションが進んで還元されるといいと思っています。

清野:続いて、赤沼さんお願いします。

赤沼:我々もスタートアップでやっている側として、立ち上げスピードの速さを今まで活用してきたし、今後も活用していきたい。Railsも7にまでなって、特にバックエンド側の処理が相当作り込まれているのではないかと思っています。フロント周りは今も動きがあるので、今後はより進化していくんだろうと思っている。

我々もそこをうまく使えるようにしていきたいので、適材適所でRailsのよさを活かせるところでは、きちんと活かしていこうと思います。変にこだわりすぎず、サービスを提供する側としてはほかの選択肢も含めて、目的のためにきちんと道具を選択していくことを意識しながらうまくRailsのおいしいところを味わっていきたい。

複数のRailsのDBにまたがったデータのやり取りは本来やるべきではない

清野:以上でトークセッションを終了しますが、1つ答えられなかった質問があるので、それだけうかがいます。「ユニファが、複数のRailsのDBにまたがってデータのやり取りをする話を、難しいところやよかったところなどもう少し聞きたいです」。

赤沼:大前提として、本来やるべきではないと思っています。APIやサービスを介してではなく、複数のRailsから1つのDBを直接Active Recordから参照することは、やるべきではないと思っています。

スキーマ管理、特にマイグレーションは、基本的にそれぞれがActive Recordで参照しますが、何か変更を加えようと思った時には片方からマイグレーションをかける構成になっています。

例えばAとBというプロダクトがあって、「Bのほうからこういう変更をかけたいんだけど、マイグレーションはAのほうだけで管理しているので、Aのほうにマイグレーションを追加して、そのためにリリースしなきゃいけない」といったことになる。本来自分が関与しなくてもいいところを互いにしなきゃいけない点は、すごくつらみがありますよね。

DBの障害を含め、何かあると両方に影響するので極力やるべきではない。我々もあくまでやむを得ずそうなっている部分があるので、できるだけ早い段階で解消していきたいと思っているところです。これで回答になっていますか?

清野:回答になっていると思います。本日のトークセッションは以上です。貴重なお話を聞けてとても楽しかったです。ありがとうございました。

赤沼:ありがとうございました。

櫻庭:ありがとうございました。