ゼロから Rails チュートリアルをやってみた話


三行で要約

Rails チュートリアルについて

Ruby on Rails はプログラミング言語 Ruby を使って Web アプリケーションを作るためのフレームワーク。

Rails チュートリアルは Ruby on Rails の初心者向けに Twitter ライクな Web アプリケーションを一から作るという基本無料(最新版は 4 章から有料: 980 円+消費税)の教材で、毎日 12 時間 + 休日を丸々使って 2 週間1 ヶ月かかる程度の分量がある1

最後までやるとこんな感じの Web アプリケーションができる。

rails-example

背景

プログラミングを始めた当初から TypeScript + Node.js を使っているのだが、 Web アプリケーションの開発に携わる身として全く Ruby on Rails に触れたことが無いのもどうなんだ??と感じていた。そんなときとある筋から勧められたこともあって、 Rails チュートリアルを一通りやることにした。

事前に Ruby を書いた経験は完全にゼロ。結果としては、 Ruby 経験なしで取り組むのは無謀だった。仕事でアプリケーションを作るレベルには全く達してはいないが、Rails がどういうものか雰囲気はつかめたと思う。

結論から: 自分の Ruby on Rails に対する印象

まず明らかに優れている点として、機能を作って一通り動くまでが異常に早い。早いというより速い。雑な表現をすると「Web アプリケーション開発 RTA」のような存在だと思った。

自分なりに考えた理由としては、

  • そもそも Ruby 自体が記述量を減らす工夫をいろいろしていそう
    • 作者の思想?
  • Rails がコマンドで自動生成するコードや組み込みの関数、特殊な記法でコードを書く量が大幅に減る
    • 第 2 章を除いて scaffold を使わないが、それでも早い
    • Web アプリケーションフレームワークって何なんだ?と不思議に思っていたが、以下の要素を集めたものということが分かってきた
      • ORM
      • ファイルをいい感じに連結してまとめるためのモジュールバンドラー
      • 便利なヘルパー関数やクラスを集めたライブラリ
      • ビューのテンプレート
      • フレームワークの思想に沿った雛形のコードを自動生成したり定型的な作業(例えば migration 実行や seed 投入)を自動化するコマンド
  • Rails ではアプリケーションを構成する概念が明確に定義され互いに密結合しているので、どこに何を書くべきかが明確
    • ビジネスロジックやデータの操作を行う関数は全てモデルに書く
    • ルーティングでどのコントローラーを呼ぶかを決める
    • コントローラーが権限の制御をしつつモデルを呼んでビジネスロジックやデータベースの操作を実行する
    • ビューは erb で組み立て、コントローラーからパラメータを渡して描画する

というところがある。

しかしながら、この早さは Ruby と Rails に慣れている人が使ってこその早さであって、初心者は Rails のやり方を理解して自分の手で実践するまでに苦労すると思う。よくいえば「魔法」みたいな存在。慣れていない人は恩恵を受けるのが難しいし、逆に Rails に慣れている人を何人か集めたら物凄い早さで Web アプリ作れそう。

また、自分が気になった点として、モデルが DB のテーブル定義と 1:1 で対応(n:1 も可能?)していて、データの操作とビジネスロジックをふんだんに含みそうなところがある。これは欠点というか状況に応じて評価が変わる点で、コントローラーとモデル、ビューの関係がシンプルであれば特に困ることは無いと思う。

チュートリアルで作る単純な Web アプリケーションのモデルでも結構いろいろ書かれている状態になる。

rails-model-code

あとフロントエンド周りは気になった。クライアントサイドで仮想的な DOM を使って必要に応じてサーバーから取得したデータを使って更新があった箇所だけ再レンダリングする、というやり方はあまり Rails には合わなさそうな気がする。 もちろん、やってる会社はたくさんあるだろうし不可能ということは無いだろうけど…

結局のところは長所と短所は表裏一体でそれぞれをどう評価するかというだけの話かもしれない。経験者を数人集めてそれなりの機能を備えた Web アプリケーションを素早く作るのにはとても向いてそう。10 年以上にわたって多くの成功したスタートアップで使われてきた理由が分かった。2

要約

第 1 章から第 14 章までの内容を一通り要約してみた。ちょっとだけ自分の感想が入っている。

第 1 章 ゼロからデプロイまで

Ruby on Rails の簡単な説明、環境設定、 Cloud9 や Git/GitHub など基本的なツールの使い方、サンプルのアプリケーションを Heroku にデプロイする方法などを教えてくれる。

Rails Tutorial では Cloud9 という AWS のクラウド IDE を使っている。これは環境設定の手間を省いてミスを防ぐためらしい。私は自分が使い慣れている Visual Studio Code とターミナルで進めることにしたが、特に問題はなかった。

rails new で指定ディレクトリに簡単に Rails アプリケーションのスケルトンを作れるのは(create-react-app みたいで)とても便利だ。Rails 使ってる人からすると当たり前のことなのだろうが、 Web アプリケーションのディレクトリ構造を考えるのは面倒だし、これに沿ってやれ!!というのを強制された方が他人や他社のコードを読む上で楽そう。少なくとも Rails が向いているアプリケーションでは。

なお、 rails new すると大量のディレクトリとファイルが生成されて初見では意味不明なのだが、デフォルトでどのディレクトリに何が格納されているかは本章内で説明されている。

最後に何も機能がないシンプルな Web アプリを Heroku にデプロイしインターネットからアクセスできるようにする。 Heroku へのデプロイはアカウントを作って CLI からログインし Heroku にリポジトリを push するだけでよくて楽。3

第 2 章 Toy アプリケーション

ユーザーや投稿を作成したり削除したりするおもちゃ(Toy)のようなアプリケーションを作成しながら Rails の便利な機能を学ぶ。

まずはデータモデルを考え、 scaffold を使ってデータを取得・操作するコードを自動生成する。これは短時間でアプリケーションを作るために非常に強力なツールだが、 Rails アプリケーションの初心者がこれを使うとアプリがどうやって動いているのか全く分からなくなってしまうそうなので第 3 章以降では一切使用しない。

scaffold では定義したデータモデルに沿って実際のデータを作成 / 更新 / 削除をするためのルーティング、 Model / View / Controller を自動生成する。例えばチュートリアル内で定義された User モデルについては、config/routes.rb/users のルートが Users Controller の index に割り当てられており、 Controller はアクションを実行して View の .erb を呼びだし結果として生成された HTML をルーターに返す。

また、 ActiveRecord を使った簡単なデータモデル同士の関連付けを学ぶ。

このように、ブラウザから操作をしたときに Rails のそれぞれの部品が何をしているのかを簡単に解説してくれる。第 3 章以降はこの scaffold を使って自動生成されるコードを手動で実装したり穴を埋めていくことで Rails の使い方を理解していく。

第 3 章 ほぼ静的なページの作成

静的なページの生成やそれに対する自動テストを実装する。

rails generate HogeController fuga piyo のように generate コマンド(逆は destroy コマンド)でルーティングや Controller, View を生成し、それを編集していく。

さらに、アプリケーションが期待通り動作しているか確かめるために自動テストを追加する。まずは Controller のテストを書き、Model のテストや統合テストは別の章で行う。

テストは「実行可能なドキュメント」ということができ、バグを発見しやすくなるため一度上達すれば確実に開発速度が上がる。4

Controller のテスト自体は rails generate コマンドの実行時に /test/ 以下に自動生成されるので、これを変更していく。未実装のアクションをテストして故意に失敗させ、そのメッセージを読みながらテストや実装を修正していく。

個人的にこの方法は仕様を理解するのに良いなと思っていて、アプリケーションが何がどうなってるのか分からない内は特にテストを失敗させて仕様を学んでいくことで効率よく学習できそうだと感じた。ドキュメントがあるならそっち読んだ方が早いけど。

第 4 章 Rails 風味の Ruby

最新のチュートリアルは 4 章から有料だったので、少し古い ver 5.1 を読むことにした。とりあえずやってみて良さそうだったら有料版を買おうかなと考えていたが、気づいたら最終章までやってしまった。Rails 6 で古いチュートリアルを進めるとたまにテストが落ちるので注意。

4 章では Rails で Web アプリケーションを開発する際によく登場する Ruby の機能、概念などを紹介している。コメント、文字列、オブジェクト、メソッドの定義、配列、ハッシュ(連想配列)とシンボル、クラスと継承など。

印象的だったのはブロックを使ったイテレーションで、これを使うことで特定のデータの塊に対してコードを繰り返し実行することができる。同じような機能はほとんどのプログラミング言語に備わっていると思うけど、 Ruby のブロックはかなり簡潔に書ける気がする。 https://docs.ruby-lang.org/ja/2.7.0/doc/spec=2fcall.html#block

Ruby 書いたことなかったので役に立ったけど、本来は Ruby 書けるようになってから読むべきコンテンツなので今からやる人は別のところで Ruby を勉強してください。

第 5 章 レイアウトを作成する

アプリケーションに簡単なレイアウトや Bootstrap による CSS を追加していく。また、 .html.erb 内で使う Rails のヘルパー関数を紹介してくれる。

本章では Rails のモジュールバンドラーである Asset Pipeline や、静的なページへのルーティングを追加してページから遷移するためのビューの書き方などが説明されている。

新しい Rails 6 を使って古いチュートリアルを勧めている場合は途中の javascript_include_tagapplication.js が無いよというエラーが出てくるが、 javascript_pack_tag に変えれば動く。 https://qiita.com/yaaasuuu/items/1d29954fda1f5fb8fc27

第 6 章 ユーザーのモデルを作成する

第 6 章から第 11 章までは、第 5 章までに作ってきたアプリケーションにユーザー登録やログイン、パスワードを用いた認証システムを実装し、データを保存したり取得したりする実戦的なやり方を学ぶ。

本章では、第 2 章で scaffold を使って生成したようなデータモデルの生成とデータを保存する手段を用意する。

rails generate model コマンドでモデル、テスト、マイグレーション(データベースの構造をインクリメンタルに変更する手段を提供する)を自動生成し、変更を加えていく。なお、生成したマイグレーションは db:migrate コマンドで適用できる。

自動生成されたモデルのクラスは ApplicationRecord を継承しており、 ApplicationRecordActiveRecord::Base を継承している。この ActiveRecord::Base が提供するメソッドを使ってデータの取得や操作、検証を行う。

ActiveRecord はデータベースのテーブルの行をラップしたクラス(要はインスタンスと DB のレコードをマッピングしていろいろな処理ができる ORM)で、様々な便利メソッドが用意されている。

第 7 章 ユーザー登録

6 章で作ったユーザーのモデルクラスをもとに、ユーザー登録するためのページを作成する。

一口に「ユーザー登録するためのページ」と言っても必要な画面はいろいろある。「すでに登録されたユーザーを表示する」「ユーザーを登録する(フォーム)」「ユーザー登録成功 / 失敗したときの画面」などを作る。

本章ではルーティングの定義やエラーページ追加、登録成功時のリダイレクトなどを実装し、よくあるフォーム付きのページとそのテストを完成させる。

第 8 章 基本的なログイン機構

第 7 章で追加したユーザー登録の仕組みを使って、ログインやログアウトの基本的な仕組みを実装する。

HTTP はステートレスなプロトコルなので、本来リクエスト一つ一つは独立しておりそれより前のリクエストの情報を利用することはできない。したがって、ユーザーのログインが必要な Web アプリケーションでは「セッション」と呼ばれる半永続的な接続の識別情報をクライアントとサーバーで持つ。

Rails でセッションを実装する方法として一般的なのは cookie を利用すること。セッションはサーバー上に保存されるが Active Record オブジェクトではないのでユーザー登録や削除とは少し実装のやり方が異なる。

ログイン/ログアウトを実装したらログイン状態を判定するヘルパー関数を実装して、「ログインしているユーザーのみがこのページを見られる」等のテストを簡単に追加できるようにする。

第 9 章 発展的なログイン機構

第 8 章で追加した基本的なログイン機構では、ログアウト時にセッションが破棄され再度ログインが必要になるようなシンプルな実装をしていた。実際の一般的な Web アプリケーションでは cookie を使ってログイン情報を記憶することが多いので、本章ではそれを実装していく。

また、Cookie を盗む方法は幾つかあるので、盗まれてもセッションハイジャックされないように cookie に保存するセッショントークンを暗号化する。

Rails には、このような発展的なログイン機構を簡単に作るための便利な機能がいろいろ用意されている。

第 10 章 ユーザーの更新・表示・削除

第 7 章で作ったユーザー登録の機能を拡張子、ユーザーの編集や削除、ページネーションを含む一覧表示を行えるようにする。また、それらの機能を使う管理者として新たなロールのユーザーを追加し、一般のユーザーにはユーザーの編集や削除などの操作ができないようにセキュリティ上の制御機構を追加する。

新しい Rails で 5 以前の rails チュートリアルを進めている場合は test で update_attributes メソッドを使っている箇所があるが、 rails 6.1 以降では非推奨になっているため動かない。該当箇所を update に書き換えると動くようになる。

第 11 章 アカウントの有効化

第 10 章までのアプリケーションでは、登録したユーザーはログインすれば直ちに全ての機能を使えるようになっていた。しかし、一般的な Web アプリケーションではメールアドレスを使ってアカウントを作成した際に本当にそのメールアドレスの所有者であるかを確認する必要がある。

第 11 章ではメールを使ってアカウントを有効化するためのトークンを生成しそれをメールで送付、メールに記載されたリンクをクリックすることでアカウントを有効化する機能を実装する。

Rails でアプリケーションを作るときの流れ(↓)がよく分かるいい章だった。

  1. rails generate
  2. テスト書く(失敗)
  3. 実装
  4. テスト(成功)- 必要に応じて migrate & seed 投入

第 12 章 パスワードの再設定

第 11 章で追加したアカウントの有効化メールを使って、パスワードの再設定を実装する。

基本的な手順は以下の通り。

  • ユーザーがパスワードの再設定をリクエストすると、メールアドレスをキーにしてユーザーを見つける
  • 該当ユーザーがいれば再設定用トークンとそれに対応する再設定用ダイジェストを生成する
  • 再設定用ダイジェストはデータベースに保存しておき、再設定用トークンはユーザーに送信する
  • ユーザーがメールのリンクをクリックすると、データベースに保存しておいた再設定用ダイジェストと比較して認証する
  • 認証に成功したらパスワード変更用のフォームをユーザーに表示する

再設定機能を使ってアカウントを乗っ取られないように、再設定用のリンクには短い期限を設定することと、再設定用のダイジェストを使うことが重要。

第 13 章 ユーザーのマイクロポスト

Twitter のかんたんなクローンを作るためにユーザーが投稿するためのモデルやコントローラー、基本的なビューを作成する。さらに、そのビューにユーザーを関連付け、結果を処理し表示するために必要なフォームを作成する。

個人的には第 11 章とこの章が Rails の威力、というか開発の早さを実感できると思う。ユーザーが投稿する画面や投稿一覧のフィードを一瞬で作れて、一気に Web アプリケーションっぽさが増す。初期の Twitter は Ruby on Rails を使って作られたらしいけど、それも納得できる便利さだった。

新しい Rails で古いチュートリアルを進めている場合はこの章の途中で謎に NameError というエラーでテストが落ちるのでこれをやる必要がある(spring を再起動したら治った)。 https://qiita.com/yokoyan/items/0f82fc3eede75cd6db55

第 14 章 ユーザーをフォローする

最終章。

13 章までで作った Twitter ライクな Web アプリケーションに他のユーザーをフォロー・フォロー解除できる仕組みと、フォローしたユーザーの投稿を表示する機能を追加する。ある機能を実現するためのデータをどうモデリングするか、 SQL を利用したデータの取得の工夫などを取り扱う。また、ちょっとした jQuery を通じてフォロー・フォロー解除の Web インターフェースを追加する。

最後にサンプルとして作ったアプリケーションの機能を拡張するためのアイデアや今後役に立つであろう読み物を紹介して終了。

分からないことがあったら Ruby on Rails ガイドという Web サイトを見ればいいらしい。

最後に

Rails チュートリアル、とても長いけど「フレームワークってこんなことしてるんだ」というのを掴むのには良い教材なので、興味ある人はやってみてはどうでしょうか。

これを 1 周やっただけでは自力でアプリケーションを開発できるようにはならないけど、 Ruby にしても他の言語で Web アプリケーションを作るにしてもこれをやった経験は役に立つと思う。

Footnotes

  1. 最初に推薦文を書いてる人が「3 日で終わらせました」って書いてあったけど絶対嘘だろって思う分量だった。

  2. 日本だと freeeクックパッド、アメリカだと GitHub初期の Twitter が有名?AirBnB も創業から最近まで?ずっと Rails 使ってたらしい(Rearchitecting Airbnb’s Frontend)。

  3. ちなみに Heroku では利用開始時にイタリアに住んでるか聞かれるのだが、これはイタリア民法 1341 条で明示的に同意が必要な内容が利用規約内に存在するらしい。イタリア以外はいいのか??

  4. テストをいつ何に対して書くかは流派が分かれるが、アプリケーションのコードより明らかにテストコードが短くシンプルであれば先にテストを書くほうがよいと思う。