Railsで初めての自作ブログエンジン開発記
福岡でWebデザインを学び、今は東京でアプリのUI設計やフロントエンド開発を中心に取り組んでいます。普段はクライアントワークが忙しく、フレームワークの中身まで深く触れる機会が少ないと感じていました。ある日、知人から「Railsの仕組みをもっと知りたければ、簡単なブログエンジンを自分で書いてみるといい」とアドバイスされたのがきっかけです。
実際に手を動かしてみると、普段何気なく使っているgenerateコマンドやscaffoldの裏側で何が起きているのかが少しずつ見えてきました。既存のRails Wayに乗っかる開発は確かに生産性が高いのですが、その便利さの本質は自分で書いてみるとよく分かります。本記事では、その過程とつまずきを整理してみます。
完成形のイメージは「記事とコメントが投稿でき、Markdownで書ける、管理画面は最低限」という小さなものです。機能は最小限に絞り、gemもActiveRecordとActionView以外は極力使わない方針にしました。Rails本体が提供する機能を素のまま使う構成を目指しています。
実装に入る前に、公式ドキュメントとRails Guidesの該当ページを繰り返し読み込みました。ネットで断片的な情報を拾うより、まず公式の説明を丁寧に読む方が後々遠回りにならないと実感しています。本記事は、その備忘録も兼ねた内容です。
自作に至った動機
普段の案件では要件に合わせてRailsの各機能を組み合わせることが多く、知識は増えていきます。ただ「ある機能をゼロから設計した経験」が少ないことは自覚していました。ブログエンジンは題材として分かりやすく、投稿・一覧・詳細・編集・削除という基本サイクルをすべて実装できます。RailsのMVCを一通り体験できる点でもぴったりでした。
もう一つの理由は、仕事で関わる他のフレームワークとの比較をしたかったからです。LaravelやDjangoなどと同じくらいRailsの独自思想を理解しておきたく、コードを書きながらその流儀を体感することにしました。結果としてCoC(Convention over Configuration)の意味が腹落ちしています。
プロジェクト構成とルーティング
まずrails newで生成されたディレクトリ構成を確認しながら、不要なファイルを削ぎ落としました。最終的に残したのはapp/controllers、app/models、app/views、config/routes.rb、db/migrateくらいです。config配下も複雑になりすぎないよう、環境別の初期設定は最小限に抑えました。
ルーティングはresources :posts do resources :comments endのようにネストさせて、RESTfulなURLを心がけました。config/routes.rbにはルートパスやヘルスチェックも最小限に定義し、Rails Wayに則った形に整えています。ヘルパーメソッドや一部の自動生成パスも意識的に使うようにし、Railsらしい書き方を学びました。
モデルとマイグレーション
Postモデルにはtitle、body、published_atを持たせ、Markdownのレンダリング用にbody_htmlカラムも追加しました。Commentモデルはpost_id、author、bodyという最小構成です。マイグレーションファイルは日時ベースの命名規則を守り、bin/rails db:migrateの流れを体感しました。
ActiveRecordのアソシエーションやバリデーションも手作業で記述しています。belongs_toやhas_manyの意味を一つずつ確認しながら書いたことで、リレーションの仕組みが頭に入りました。バリデーションエラーメッセージの表示部分まで丁寧に組み立てたので、フォーム周りの動きがイメージしやすくなっています。
コントローラとCRUD処理
PostsControllerではindex、show、new、create、edit、update、destroyの七つのアクションを順番に実装していきました。Strong Parametersの使い方や、before_actionで共通処理をまとめる方法など、Rails特有の書き方を地道に確かめています。renderとredirect_toの使い分けも何回か試しながら習得しました。
コメントの投稿は同じコントローラに入れず、CommentsControllerとして独立させました。POSTの後に親記事の詳細ページへ戻す流れを自分で組み立ててみると、HTTPメソッドとURL設計の関係がよく分かります。Railsが自動で組み込んでくれるCSRF対策の恩恵も改めて感じました。
ビューとマークダウン対応
テンプレートはERBで書き、基本構造はapplication.html.erbに集約しました。レイアウトにはシンプルなCSSのみ適用し、装飾よりも構造の見通しを優先しています。パーシャルを使った部品化も少しずつ進め、ヘッダーやフォームの共通化を行いました。
Markdownのレンダリングは外部gemに頼らず、Ruby標準のライブラリだけで簡易的に対応しようと試み、最終的にはkramdownを採用しました。before_saveコールバックでHTMLを生成し保存する方式にし、表示時の負荷を下げる工夫も入れています。Markdownで書ける体験はやはり快適です。
つまずきと学び
開発中につまずいたのは、ルーティングの名前空間とform_withの挙動でした。特にlocal: trueとlocal: falseの使い分けは実際に書いてみないと分かりにくい部分でした。エラー画面と向き合いながら、一つずつRailsの作法を覚えていきました。
Strong Parametersを渡し忘れたときに500番台ではなく422番台が返る理由など、普段意識しない挙動も手を動かしたからこそ理解できた部分です。ログの見方やデバッグ手法も、少しずつ馴染みのあるものになってきました。詰まった箇所を振り返ると、フレームワークに対する解像度が確実に上がっています。
今後の拡張余地
現在は投稿とコメントの基本機能のみですが、検索機能やタグ機能、ページネーションあたりは自然な拡張候補です。Railsにはkaminariやransackといった定番gemがありますが、それらに頼らずに自作してみるのも面白そうです。検索アルゴリズムの動きを分解して書く経験は、きっとまた別の学びになるでしょう。
認証周りも今後の課題です。現状では管理画面の保護を簡易的なセッション処理で凌いでいますが、Rails 7以降に標準で備わった認証機能generatorを改めて検証してみたいと考えています。機能の詰め込みすぎず、本質的な仕組みを理解する姿勢を忘れないようにしていきたいところです。
興味があれば、suema-rのような個人ブログやポートフォリオサイトをRailsで動かしてみるのも良い勉強になります。実際に動くものを作りながら学ぶと、座学だけでは得られない筋肉のような知識が身につきます。小さな題材からでも、自作ブログエンジンの魅力は十分伝わるはずです。