delhi09の勉強日記

技術トピック専用のブログです。自分用のメモ書きの投稿が多いです。あくまで「勉強日記」なので記事の内容は鵜呑みにしないでください。

DjangoユーザーがRails入門してみて感じた違い

はじめに

私は仕事で3年以上Djangoを使っているが、副業でRailsを使う機会があった。同じそれぞれの言語を代表するフルスタックフレームワークだからそんなに違わないと思っていたらけっこう違ったので、感じた違いをメモしておきたい。

目次

  • フロントエンドに対する考え方
  • バージョンアップポリシー
  • CoC(Convention over Configuration)
  • モジュールのインポート
  • Formの有無
  • Modelの仕様の違い
  • Migrationファイルの扱い方の違い
  • ファイルの扱い
  • applicationの有無
  • 認証機能の有無
  • ググラビリティ

フロントエンドに対する考え方

Djangoはよくも悪くもフロントエンドに対して無関心である。

対して、RailsDHHの思想もあるのだろうが、フロントエンドに独自のやり方で関わろうとしている。

具体的にはRailsの実行環境にはYarnが必要であり、またRailsというFWは以下のようなものを包含している。

  • Turbolinks
  • Webpacker
  • Sprockets
  • Stimulus

私が関わったPJではTurbolinksの挙動に苦しめられた。

昨今主流の、RailsAPIサーバーとして使い、FEはReactやVueを使うという場合はあまり関係ないだろうが、画面もRailsで実装する場合はこれらも抑えておく必要がある。

最初からAPIサーバーとしてしか使わないと決めている場合は、RailsにはAPIモードというものがある。 railsguides.jp

バージョンアップポリシー

Django

Djangoはメジャーバージョンアップ時に大きな機能追加もない代わりに後方互換性を大事にしており、かなり安定していると感じている。実際に私もバージョンアップをしたことがあるが、主に問題になるのは依存しているライブラリが新バージョンのDjangoに対応していないとかであって、Django自体のバージョンアップで苦労したことはあまりない。

blog.pyq.jp qiita.com

Rails

対して、Railsは大きな機能追加や破壊的な変更が多い。

qiita.com developers.freee.co.jp

CoC(Convention over Configuration)

RailsはCoCを徹底している。慣れなのだと思うが、命名規約が違反していて動かないことが何度かあり、明示的に設定を書いた方が楽なのになと思ったことはある。

rubyonrails.org

モジュールのインポート

Djangoには特有のモジュールのインポートの機構はないので、通常のPythonと同じようにimportを書いてモジュールをインポートする。

対してRailsではZeitwerkというものが裏で動いており、何もコードを書かなくてもモジュールをインポートしてくれる。 railsguides.jp

従って、Railsではrequire(Pythonでいうimport)を基本的に書かない。

これも慣れなのだと思うが、Djangoに慣れてる身としては以下の点で苦労した。

  • コードを眺めても依存しているモジュールがぱっと見で分からない。
  • CoCと関連するが、命名規約を間違えていたりファイルの置き場所がRails Wayから外れていたりするとインポートされない場合がある。

Formの有無

DjangoにはFWの機能としてリクエストパラメータをバリデーションする層であるFormがあるが、Railsにはない。バリデーションはModelで行う思想らしい。 speakerdeck.com

※ t_wadaさんが「FormとModelのバリデーションルールがほぼ同じだからという理由で、Form層を切ったのがDHHの慧眼」という趣旨の話をどこかのポッドキャストでしていた記憶がある。見つけたら追記しておく。

RailsにおいてはFormはデザインパターンになっている。 techlife.cookpad.com

Modelの仕様の違い

DjangoではModelは「テーブル定義書 as code」のようになっており、Modelのコードを読むとテーブル定義が把握できる。

対してRailsではModelに記述するのはバリデーションやコールバックのみで、スキーマ定義自体は書かない仕様である。(実行時にDBからスキーマ情報を取得して、メタプログラミングで動的にフィールドを生成しているらしい。)

コードからテーブル定義を把握したい場合は、schema.rbを見たり、annotateというModelにコメントでテーブル定義を自動出力してくれるライブラリを使ったりする。

Migrationファイルの扱い方の違い

先のDjangoではModelでスキーマ定義するという話と関連するが、DjangoではMigrationファイルはModelをインプットとして得られる生成物なので、基本的に人間はあまり編集しない。

対してRailsではrails generate migrationしても雛形しか作成されないので、どのようなテーブルを作成したいかは人間が生成コマンドのオプションに渡したり、自分で記述したりする必要がある。(Modelにスキーマ定義がないからインプットにできるものが存在しないので、必然ではある)

ファイルの扱い

DjangoではModelに組み込みでFileFiledImageFiledが存在する。

対してRailsではCarrierWaveなどのライブラリを使って対応するのが一般的である。

Rails5.2以降ではActive Storageが使えるようになったが、ざっと説明を読んだ感じ癖が強い機能だと感じたので、新規の案件であっても要件に合うかよく考えた上で導入したほうがいいと個人的には思っている。

railsguides.jp

applicationの有無

Djangoにはapplicationという機能の塊ごとにコードをグルーピングする概念が存在するが、Railsにはない。

ただ最近は、Railsでのモジュラーモノリスに関する議論があり、その中でコンテキストごとにモジュールを分けるという考え方が出てきてはいるようである。 logmi.jp

認証機能の有無

DjangoにはデフォルトでUserモデルと認証機能が備わっているが、Railsにはないのでdeviceなどのライブラリを使って実現する。これに関してはDjangoの方が特殊といえるかもしれない。(実際にUserモデルに設計が引きずられてしまうことがありがちである)

github.com

ググラビリティ

DjangoRailsに比べるとユーザ数が少ないこともあってか、発信者に信頼できる方が多く、ググるとすぐに良質な情報に出会える印象がある。

Railsの方がググった時にヒットする情報が玉石混合で良質な情報を探すのに苦労した。他方でRailsを使っている会社のテックブログやKaigi On Railsの発表などは現場レベルのナレッジが多くとても充実している。

ユーザー数が多いというのはそういうことなのだと思う。