開発ノート@HarikoApps

HarikoApps: https://hariko.sprkls.me

2024-07-06

Writebookのソースコードを読んだメモ #14

先日、37signalsから新しいONCEプロダクトのWritebookが発表されました!これはウェブ上で書籍を編集して公開するためのRails+Hotwireのアプリで無料で公開されています。もちろんソースコードもダウンロードできるので、早速アプリをローカルで動かしながらソースコードを見てみました。
初回リリースということもあるのかもしれませんが、全体としてとてもシンプルな実装になっていて、こんなに少ないコードでこれだけのことができるのかという驚きがありました。

Writebookの機能

  • 複数ユーザーによる書籍編集(同時編集はサポートされていなくて変更通知のみ)
  • Markdownによる編集
  • 書籍ページ編集の自動保存
  • 書籍ページの並べ替え、削除
  • ユーザーの招待
  • マジックリンクによるログイン
  • 書籍のパブリックな公開機能
  • 閲覧と編集の権限管理
  • 読み進んだページを記録するブックマーク
  • etc

Model

ファイル数はConcern含めて25程度と少ないです。書籍の執筆と公開というドメインがモデリングされて、周辺的な関心ごとはConcernに移されています。以下のような点が気になりました

  • DemoContentとFirstRunというモデルはユーザーの初回登録時の処理を行うPOROになっている
  • 本のページはLeafモデルで表されLeaf#leafableというdelegated_typeで、通常ページ(Page)、画像(Picture)、セクション(Section)のモデルを表している
  • enumは %w[ foo bar ].index_by(&:itself) のように定義されている。itself便利
  • CurrentAttributesを用いたCurrentモデル
    • Book/Accessable ConcernにてCurrent.userをデフォルト引数に渡している
  • 他デバイスからログインするためのマジックリンクのトークンはsigned_idを使って生成されている
    • 独自にトークン生成しなくても期限付きの改竄防止されたトークンが作れるのは便利なので個人的にも使いたい

Controller

  • ***ScopedというConcernが多用されている
  • Books::Leaves::MovesControllerのように仮想的なリソースも扱う設計になっている
    • Moveに当たるモデルは存在せず、Leafを動かす処理を行う
  • ApplicationController で allow_browser が使われている
  • LeafablesControllerで同時編集通知がほんの2、3行で実装されているのに驚き

Viewまわり

  • turbo_stream_action_tag :scroll_into_view, target: id のようにしてTurbo Streamを使って対象要素にスクロールできるようにしている
    • これはTurboStreamのカスタムアクションを用いている
  • StimulusのArrangement Controllerが結構大きい(400行ほど)
    • これはページ(Leaf)の並び替え機能を担当している
  • house.min.jsがActionText用MDエディタのよう
    • まだOSSで公開されていなさそう
  • 本の上にブックマークが表示される箇所と、ページ(Leaf)一覧にturbo-frameが使われているのがなぜなのかよくわかってない
    • 特に必要なさそうな箇所なので。ここはもうちょっと調べてみたい

  • lib/rails_extの下にActionTextのMarkdown対応用の拡張ファイルなどがある
    • Railsの動作を拡張したいときは同じようにするのが良さそう
  • 本のタイトルに日本語を入れたり、エディタに日本語入力するとバグる
    • 追記)これはアプリケーションのバグというよりも多言語対応は未対応と見たほうが良さそう
  • bin/setupにpuma-devのSymリンクを作る処理があったのでローカルで立ち上げるのにpuma-devを使ってみた
    • powが便利で好きだったが開発終了してしまったのでpowと同じような体験ができて嬉しい

Updated at