Ruby on Rails チュートリアル

プロダクト開発の0→1を学ぼう

学習者の躓きやすい点が改善されたRails 7 対応Webテキストがリリースされています。学習で使うときは最新版をご利用いただけると幸いです。

第6版 目次

推薦の言葉

私が前にいた会社(CD Baby)は、かなり早い段階でRuby on Railsに乗り換えたのですが、またPHPに戻ってしまいました(詳細は私の名前をGoogleで検索してみてください)。そんな私ですが、とある本を使ってもう一度試してみた結果、今度はRailsに無事乗り換えることができました。それがこのRailsチュートリアルという本です。

私は多くのRails関連の本を参考にしてきましたが、真の決定版と呼べるものは本書をおいて他にありません。本書ではあらゆる手順が『Rails流 (the Rails Way)』で行われています。最初のうちは慣れるまでに時間がかかりましたが、この本を終えた今、ついにこれこそが自然な方式だと感じられるまでになりました。また、本書では多くのプロが推奨するテスト駆動開発をほぼ全編に取り入れています。実例を使ってここまで分かりやすく解説された本は、本書が初めてでしょう。極めつけはGitやGitHub、Herokuの実践までも含めている点です。このような実践もチュートリアルに含まれているため、読者はまるで実際のプロダクト開発を体験しているかのような感覚が得られ、それでいてチュートリアルとして見事に一本化されています。

物語のような一本道の構成も素晴らしいです。私自身、演習問題もやりながら、このRailsチュートリアルを3日間かけて一気に完走しました1最初から最後まで、途中を飛ばさずにやるのが有益な読み方です。それでは、楽しんでお読みください!

Derek Sivers (sive.rs)2 CD Baby 創業者

  1. 3日間で完走できる人は例外です! 実際には数週間〜数ヶ月かけて進めるのが一般的です。
  2. たった3分の有名なTED動画『社会運動をどうやって起こすか』を視聴された方もいるのではないでしょうか。その方からの推薦の言葉です。

謝辞

Railsチュートリアルは私の以前の著書『RailsSpace』と、当時の共著者Aurelius Prochazkaから多くを参考にさせてもらっています。Aureには、協力と本書への支援も含め、感謝したいと思います。また、RailsSpaceとRailsチュートリアルの編集を担当したDebra Williams Cauley氏にも謝意を表したく思います。彼女が野球の試合に連れて行ってくれる限り、私は本を書き続けるでしょう。

私にインスピレーションと知識を与えてくれたRubyistの方々にも感謝したいと思います:David Heinemeier Hansson, Yehuda Katz, Carl Lerche, Jeremy Kemper, Xavier Noria, Ryan Bates, Geoffrey Grosenbach, Peter Cooper, Matt Aimonetti, Mark Bates, Gregg Pollack, Wayne E. Seguin, Amy Hoy, Dave Chelimsky, Pat Maddox, Tom Preston-Werner, Chris Wanstrath, Chad Fowler, Josh Susser, Obie Fernandez, Ian McFarland, Steven Bristol, Pratik Naik, Sarah Mei, Sarah Allen, Wolfram Arnold, Alex Chaffee, Giles Bowkett, Evan Dorn, Long Nguyen, James Lindenbaum, Adam Wiggins, Tikhon Bernstam, Ron Evans, Wyatt Greene, Miles Forrest, Sandi Metz, Ryan Davis, Aaron Patterson, Pivotal Labsの方々、Herokuの方々、thoughtbotの方々、そしてGitHubの方々、ありがとうございました。最後に、ここに書ききれないほど多くの読者からバグ報告や提案を頂きました。ご協力いただいた皆様のおかげで、本書の完成度をとことん高めることができました。

丁寧なレビュー、技術的なフィードバック、そして役立つ提案をしてくれたAndrew Thaiに感謝します。また、Learn Enough to Be Dangerousの共同創業者であるNick MerwinとLee Donahoe、日々のチュートリアル制作をサポートしてくれてありがとう。

最後に、たくさんの読者の皆さん、そして、ここに挙げきれないほど多いコントリビューターのみんな、バグ報告や提案をしてくれてありがとう。彼ら/彼女らの多くの手助けに、最高の感謝を。

著者

マイケル・ハートル(Michael Hartl) は、Webサービス開発を学ぶときによく参考にされる『Ruby on Rails Tutorial』の著者であり、LearnEnough.comの共同創業者でもあります。カリフォルニア工科大学で物理学の講師を務めた経験があり、そのときにLifetime Achievement Award for Excellence in Teachingを受賞しました。

ハーバード大学卒業後、カリフォルニア工科大学物理学博士号を取得。シリコンバレーの有名な起業プログラム Y Combinator の卒業生でもあります。

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

Railsチュートリアルへようこそ!

本チュートリアルの目的は、皆さんにWebサービス開発で必要になる基礎知識を学んでもらうことです。本チュートリアルで学んだことは、Webサービス開発者としての仕事を探したり、フリーランスとしてのキャリアを始めたり、自分のWebサービスで起業する場面などで役立ちます。既に開発の経験があれば、より短期間でWebサービス開発の流れを掴めるでしょう。

Railsチュートリアルでは汎用性の高いスキルの習得を優先しています。今後他のプログラミング言語やフレームワークも学ぶ予定の人にとっても、ここで学んだWebサービス開発の基本が役立つように仕上げています。

本チュートリアルでは『Ruby on Rails』を題材にしています。これはWebサービス開発の基本を学ぶ上で、これ以上ふさわしいフレームワークは無いと考えているからです。

コラム 1.1. Ruby/Railsの実績

Ruby on Rails(略称『Rails』)は、プログラミング言語『Ruby』で書かれたフリーかつオープンソースのWeb開発フレームワークです。

Railsは本格的なWebサービスを開発するツールとして急速に有名になり、海外ではGitHubShopifyDisneyAppleAirbnbSoundCloudイギリス政府などで採用され、ドイツの政府系ファンド(STF)もRuby/Railsを支援しています。また日本国内でもCookpadnotefreeeマネーフォワードYAMAPCrowdWorksQiitaZennGame8アカツキpixivSTORES駅すぱあとスタディサプリ、自治体に導入されているつながる相談などで採用されています。Rubyを採用している上場企業は50社以上にのぼり、2021年にはRailsを使い続けるGitLab約1.2兆円の時価総額で上場、2024年のRails求人数も右肩上がりとなっています。1

Webサービス開発にはRails以外にも多くの選択肢がありますが、Railsのアプローチは豪快かつ強力で、個人開発から上場まで幅広い場面に使えます。初めてWebサービスを作る個人にとってはRailsの標準機能だけで開発でき、大成功したときも高い拡張性を兼ね備えています。また大企業がシングルページアプリケーション(SPA)やモバイルアプリと組み合わせて開発したい場面でも、Railsは素晴らしいバックエンドを提供できます。

加えて、RailsにはPHPやNode.jsのフレームワークにも影響を与えた設計哲学があります2。現在も毎年のように新しいフレームワークが公開され、多くの開発者が議論を交わしていますが、Railsの作者であるDHH(David Heinemeier Hansson)は設計哲学について一貫して次のようにコメントしています。

Railsが登場した当初から現在に至るまで、フレームワークに関する様々な議論がありますが、Railsが大切にしている設計哲学は今も残り続けています。すなわちプログラミングの慣習をパターン化すること、不要な選択肢を外すこと、そして最適なデフォルト設定を提供することが大切であり、生産性を劇的に向上させるのです。

この一貫したRailsの設計哲学20年以上生き残り続けているおかげもあって、本チュートリアルで学べるWebサービス開発の基本もリリース当初からほとんど変わらずに安定し続けています。つまり皆さんが本チュートリアルを通してこれから学ぶ知識と経験についても、当分古びることなく役に立つと言えるでしょう。

そしてRailsは今も絶え間なく進化を繰り返しています。たとえばRails 6では、並列テスト複数データベース対応などの高度な機能が追加されました。“scalable by default” というYouTube動画 (英語) では、当時GitHubのエンジニアだったEileen Uchitelleさんによって『アプリがどれほど大きく成長してもRailsはスケールできる』と解説されています。

また画期的な進化を遂げたRails 7.0では、HotwireTurboといったフロントエンドの新しい技術と統合されました。これにより複雑さを抑えつつ、シンプルな構成のまま快適なユーザー体験 “も” 提供できるようになりました3。さらに2023年10月にリリースされたRails 7.1では、Dockerを使った開発がしやすくなり、GitHubShopify級の大規模なWebサービスでも高いパフォーマンスを出せるようになりました。

Railsの実績は、今も動き続けているWebサービスとその成果を見れば明らかでしょう。共同開発プラットフォームとして絶大な人気を誇るGitHubには安心して寄りかかれる高い安定性があり、オンラインストア構築(EC)の分野で大成功を収めたShopifyカナダ最大級の上場企業になりました。このような多くの成功した企業政府自治体福岡島根三鷹など)がコミュニティを支援し続け、RubyやRailsが進化し続けているという点は、これから学ぶ私たちにとっても大きなメリットです。

Railsは、2003年に1人のWebエンジニアが仕事の合間に手掛けたことから始まったとは思えない素晴らしい出来です。当時Railsを選ぶことは最先端であると同時に20年以上生き残るか分からないリスクもありましたが、今ではそうした駆け引きなしにRailsを選べます。

Railsは数々の事例で実証された高い生産性を備え、有用なコミュニティによって支えられています。Railsは、本格的なWebサービス開発にふさわしい魅力的なフレームワークなのです。

まずは学習ロードマップで「全体像」を押さえよう

Railsチュートリアルでは「学習の流れ」をイラストでまとめています(図 1.1)。自分に合った学び方を見つけていきましょう。詳細は次の「前提知識」で1つずつご紹介していきます。

6
図 1.1: Railsチュートリアルの学習ロードマップ(学習の流れから引用)

1.1 前提知識

Railsチュートリアルでは、題材となるSNSを作りながらプロダクト開発に関する様々な知識を学んでいきます。具体的には、Rubyコマンドラインによる実践的なプログラミング、Gitテストを使ったコード管理、セキュリティに関する設計と実装、HerokuAWSを使ったWebサービスの公開方法などが学べます。

ゼロから学べたという事例もありますが、プログラミングの学習経験があると良いです。「プログラミングが初めて」という人向けにも、初心者向けプログラミング学習サービス「Progate」と提携し、Webの基礎知識が学べるコースを用意しています。Progateは学習の難関である環境構築が不要で、ブラウザ上でコーディング体験ができるため、特にプログラミング未経験者にオススメです。このまま1章ずつを読み進めても大丈夫ですが、もし章の途中で「難しい」と感じたら下記の関連するコースまたはWeb開発コース(Ruby on Rails)で基本を押さえましょう。

上記コースを学んだ上で、それでも「難しい」と感じる方は下記の追加コンテンツや質問対応サービスもぜひご検討ください。

Railsチュートリアル実践入門シリーズ

Progateと本書の違いの1つに、「ブラウザで開発するかローカルで開発するか」があります。実践入門シリーズではこれまでブラウザで学習してきた人を対象として、ローカル環境での開発に役立つ実践的な知識を詰め込んでいます。例えばコマンドラインやテキストエディタの環境構築や、GitやGitHubに特化した解説など、ローカル環境で躓きがちな部分を重点的に補足しています。

また、ローカル環境の難しさと同じことが、複雑かつ高度になっていくWeb技術にも言えます。本書ではRuby on Railsという実践的なWeb開発フレームワークを題材としていますが、JekyllSinatraといった比較的シンプルで小さなフレームワークを間に挟むことで、段階的にWeb技術を学ぶこともできます。

実践入門シリーズは今後も追加される予定です。最新情報は公式のnoteマガジンYouTubeチャンネルからも発信していくので、ぜひチェックしてみてください。

Railsチュートリアル解説動画

『ただ学ぶのではなく早く学びたい』といった方向けに解説動画質問対応サービスも提供しています。企業の社員研修大学/大学院の講義などでも採用されている好評のコンテンツとなっているので、効率的に学びたいときはぜひご検討ください。

Ruby on Railsガイド

本書で紹介する各機能を詳しく知りたいときに役立つのが、1,600ページを超えるRuby on Railsの大型リファレンス『Railsガイド』です。

Railsチュートリアル完走者が対象となっているので、本書を完走後、自分のWebサービスを開発するときや、仕事でコードを書く場面などでお使いください。全文検索やダークモードに対応したProプラン、法人向けTeamプラン、ダウンロード可能な電子書籍版もあります。

Railsチュートリアルの構成

本チュートリアルは、実際に動くWebアプリケーションを開発しながら学ぶ構成になっています。最初は簡単なページ表示のみですが、章が進むにつれてユーザー登録やログイン機構など、少しずつに高度なWebアプリケーションになっていきます。始めは最小限のhelloアプリ(1.3、図1.2)で各種セットアップを整え、次に少しだけ機能が増えたtoyアプリ(2章、図1.3)を体験してから、最後に本格的なWebアプリケーション『Sample App』(3章〜14章、図1.4)の開発に取り組みます。

本チュートリアルでは、あらゆるWebサービス開発で通用する一般的なトピックを中心に学べるようになっています。例えばユーザー登録やログイン機構、メールを使ったアカウント認証やパスワード設定といったトピックなどです。実際のWebサービスのほとんどでは、これらの主要な機能が盛り込まれています。それだけでなく14で完成するSample Appの最終版では、初期のTwitterを連想させるような仕組みになっています。そういえば偶然にも、Twitterも最初はRailsで構築されていましたね。(当時の開発者も「初期にRubyを選んだのは間違いではなかった」と強調しています)

それではチュートリアルを始めていきましょう!

6
図 1.2: 最初に作るhelloアプリ
6
図 1.3: 次に作るtoyアプリ
6
図 1.4: 最後につくるサンプルアプリ

1.2 さっそく動かす

本チュートリアルの特徴の1つは、難関であるローカル環境のセットアップを後回しにしている点です。本チュートリアルはブラウザで動かせる開発環境として著名なAWS Cloud9と長年に渡ってパートナーシップを結んでいます。そのおかげで、本チュートリアルではCloud9を用いることで、ローカル環境で躓きがちなセットアップを後回しにしてプロダクト開発が学べるようになっています4

ここは実に重要な点です。Rubyをインストールし、Railsをインストールし、必要な関連ツールを何から何までインストールするのは、ベテラン開発者にとってもしんどい作業になることがあります。また、お使いのOS(Windows・macOS・Linux)やOSのバージョン、テキストエディタやIDE(統合開発環境)の好みなどでセットアップ方法がバラつくため、検索で見つかった記事が自分にとっては逆効果になることもあります。

だからこそ、クラウド統合開発環境すなわちクラウドIDE( 1.2.1)は、特に初心者にとって役立つサービスとなります。クラウドIDEはWebブラウザで簡単に動かせるので、読者のOSがそれぞれ違っていてもまったく同じに動きます。しかも作業中の状態を保持してくれるので、チュートリアルをしばらくお留守にしてから戻ってきても以前の状態からすぐに再開できます。

とはいえ、いずれはお使いのローカル環境でセットアップする必要が出てきます。特に業務で開発する場面では、ある程度以上の熟練度コラム 1.2)も必要になるでしょう。しかし焦ってはいけません。現在のベテラン開発者が歩んできたように、私達も少しずつ熟練に近づいていけばよいのです。

コラム 1.2. 「熟練」になるとは

Railsチュートリアル実践入門シリーズでは、シリーズを通じて「熟練(Techinical Sophistication)」をテーマに据えています。

技術的に困難な課題を魔法のように解決するには、やはりハードスキル(操作方法などの定型化しやすいスキル)とソフトスキル(デバッグなどの定型化しにくいスキル)の両面で熟練になる必要があるでしょう。Web開発やプログラミングは一般的に高度な技術とされていますが、技術は「知っていればよい」という類のものではありません。もちろん、メニュー項目をクリックしたら何が起きるかも分からないようでは話になりませんが、一方で、エラーメッセージを検索して調べたり、もう少しだけ頑張るべきか別の方法を探すべきかを見極める力も必要です5図 1.5)。

言い換えると、Webアプリケーションには動的な部品がたくさんあるので、こうした両面のスキルを身に付けるにはもってこいです。しかもRailsのWebアプリケーションの場合は、適切なRuby gemの選定方法、bundle installbundle updateの実行方法、ローカルWebサーバーが動かなくなったときの再起動方法といった技術も身に付けることができます(今私が書き連ねた用語がさっぱり分からなくてもご安心を。本チュートリアルですべて説明いたしますので)。

本チュートリアルを進めていれば、どうやっても手順通りに動かないことがあるでしょう。ハマりやすい手順についてはできるだけ補足するようにしていますが、すべての状況をカバーすることは不可能です。そうしたトラブルはむしろ、熟練になるための修練だと捉えて課題解決に取り組んでみましょう。それでも、どうしてもうまくいかないときは...「バグではありません、仕様です!」(コマンドライン編より)

6
図 1.5: 「サポート担当者のためのチートシート」(漫画: xkcdより)

1.2.1 開発環境

開発環境は、1人1人すべて異なります。なぜなら開発者は慣れてくるにつれて、自分の環境をカスタマイズするものだからです。開発環境を大別すると、テキストエディタやコマンドラインを組み合わせて使う環境と、IDE(統合開発環境)の2つに分けられます。そしてRailsチュートリアルでは、環境構築の複雑さを避けるためにAWS Cloud9という素晴らしいクラウドIDEサービスを使って進めていきます。AWS Cloud9ではRubyやRubyGems、Gitなど、Ruby on Railsの開発環境の構築に必要なソフトウェアがほとんど組み込まれています。RailsやHerokuなどの一部のソフトウェアはインストールされていませんが、これらはもちろん本書の中で説明してあります(1.2.2)。

クラウドIDEにはWeb開発に必要な三種の神器であるテキストエディタ、ファイルブラウザ、コマンドラインターミナル(図 1.6)もしっかり組み込まれています。また、クラウドIDEのテキストエディタでは、Ruby on Railsの大きなプロジェクトには不可欠とも言うべき横断的ファイル検索も利用できます6。たとえクラウドIDEを今後使うことがないとしても、コマンドラインターミナルやテキストエディタなどの開発ツールで一般にどんなことができるのかを知っておくには最適です(筆者としても他のエディタの使い方は知っておいた方が良いと考えています)。

6
図 1.6: クラウドIDEの外観

クラウドIDEを利用するための手順は次のとおりです。7

  1. Cloud9は現在Amazon Web Services(AWS)に統合されたため、Cloud9を使うためにはAWSアカウントが必要になります。AWSアカウントを既にお持ちの場合は、AWSにログインしてください。AWSコンソールに行き、検索ボックスから “Cloud9” と入力すると、Cloud9の開発環境を作成するためのページに行けます。
  2. Amazon Web Services(AWS)アカウントを持っていない場合は、AWS Cloud9のユーザー登録をします。悪用防止のためクレジットカード情報の入力が必須になりましたが、AWSには無料利用枠があるのでご安心ください。アカウントが有効になるまで最大で24時間かかりますが、著者の場合は約10分ほどで完了しました。
  3. Cloud9の管理ページ(図 1.7)に無事たどり着いたら “Create environment” をクリックし、図 1.8のような画面になるまで進めてください。「rails-tutorial」を含む名前などの情報を適宜入力して(図1.88次のページに進みます。ここではAmazon LinuxではなくUbuntu Serverを選択してから“Next step”をクリックします(図 1.9)。

    確認ボタンを数回クリックしてデフォルトの設定を受け付けると、AWSがIDEのプロビジョニングを開始します(図 1.11)。このとき、“root”ユーザーになっているという警告が表示されるかもしれませんが、この段階では無視して構いません(ここでの望ましい方法は割と複雑になるので、13.4.4のIAM(Identity and Access Management)の項で後述します)。

6
図 1.7: AWS Cloud9で新しいワークスペースを作成する
6
図 1.8: AWS Cloud9の新しいワークスペースに名前をつける
6
図 1.9: Ubuntu Serverを選択する
6
図 1.10: IDEをプロビジョニングする直前の手順
6
図 1.11: クラウドIDEの初期画面

Rubyの世界では、インデントに2つのスペースを使うのがほぼ常識になっているので、このエディタのインデント設定もデフォルトの4から2に変えておくことをオススメします。インデント設定を変更するには、右上の歯車アイコンをクリックして[Project Settings]を開き、[Soft Tabs]設定でマイナス記号をクリックして値を「2」にします(1.12)。設定の変更はその場で反映されるので、[Save]ボタンをクリックする必要はありません。

6
図 1.12: Cloud9でインデントをスペース2つに設定する

なお、クラウドIDEを使っている場合はGitHubとHerokuコマンドをセットアップする必要があります。細かな手順は 1.4.31.5.1のインストール手順で説明します。

また、今すぐ設定する必要はありませんが、クラウドIDE上でテスト環境をセットアップする際の応用的な設定は3.6で解説しています。詳細は3.6.2まで進んだときに学びましょう。

最後に、本チュートリアルはRuby 2.7.6を標準として使います。rvm(Ruby Version Manager)を利用すれば、さまざまなバージョンのRubyを指定してインストールできます9

$ rvm get stable
$ rvm install 2.7.6
$ rvm --default use 2.7.6

1.7でも後述するように、本チュートリアルではUnixのプロンプトとして$記号を使いますので、上の各行冒頭にある$記号は入力しないでください。)

Rubyのインストールが完了したら、以下を実行してRubyのバージョンを確認できます(実際に表示されるバージョンはこれと異なることもあります)。

$ ruby -v
ruby 2.7.6p219 (2022-04-12 revision c9c2245c0a) [x86_64-linux]

1.2.2 Railsをインストールする

1.2.1の開発環境には必要なソフトウェアがすべて含まれていますが、Railsそのものは含まれていません。これは意図したものです。チュートリアルを期待どおりに進めるには、Railsの正確なバージョンをインストールすることが重要だからです。

まずはインストール時間を短縮するため、Rubyドキュメントの設定を追加してみましょう(リスト 1.110。このコマンドは1回実行するだけでOKです(コマンドラインの慣習については 1.7で説明します)。

リスト 1.1: Rubyドキュメントをスキップする設定を.gemrcファイルに追加するコマンド
$ echo "gem: --no-document" >> ~/.gemrc

Railsをインストールするには、RubyGemsが提供するgemコマンドを使います。リスト 1.2のコマンドをターミナルに入力してください。クラウドIDEを使っている場合は図 1.6の右下にあるコマンドライン領域に入力してください(ローカル環境で開発している場合は通常のターミナルウィンドウに入力してください)。

リスト 1.2: バージョンを指定してRailsをインストールする
$ gem install rails -v 6.0.4

-vというオプションを使うことで、インストールされるRailsのバージョンを正確に指定できます。railsコマンドに-vオプションを使うとインストールされたことを確認できます。

$ rails -v
Rails 6.0.4

このコマンドで出力されるバージョン番号は、インストールされたバージョン(リスト 1.2)と正確に一致する必要があります。

第6版ではRails 6.1にアップグレードする演習課題を最終章で用意しています。Rails 6.1から入った新機能の中で本書に影響を与える機能はほとんど無いため、本書を最後までやり切った方であればちょうど良い難易度になっているはずです。詳細は『読み物ガイド』をご参照ください。

経験上、リスト 1.3で示すようにbundlergemのバージョンも揃えておくとよいことがわかっています。

リスト 1.3: bundlerのバージョンを指定してインストールする
$ gem install bundler -v 2.2.17

bundler gemは重要です。詳しくは 1.3.1で学びます。

もうひとつインストールするものがあります。JavaScriptソフトウェアの依存関係を管理するYarnというプログラムです。ネイティブOS上で開発する場合は、自分のプラットフォームに合ったYarnインストール手順(英語)に従ってください。クラウドIDEで開発する場合は、リスト 1.4のコマンドを実行するだけで必要なツールをCDN経由でダウンロードおよびセットアップできます。リスト 1.4では、Cloud9環境でディスク容量が不足しないよう、ワークスペース環境に容量を追加するコマンドも事前に実行しています。

リスト 1.4: Cloud9環境のディスク容量アップと、クラウドIDEへのYarnインストール
$ source <(curl -sL https://cdn.learnenough.com/resize)
$ source <(curl -sL https://cdn.learnenough.com/yarn_install)

ここでapt-get: command not foundのようなエラーメッセージが出た場合は図 1.9でUbuntu Serverを選んでいない可能性があります。その場合は一度ワークスペースを削除し、新しいワークスペースを作成し直しましょう。

なお、以下のような警告メッセージがときどき表示されることがあると思います。

========================================
  Your Yarn packages are out of date!
  Please run `yarn install --check-files` to update.
========================================

そんなときは、メッセージの指示に従ってyarnコマンドを実行すればOKです。

$ yarn install --check-files

以上でインストールはおしまいです!Ruby on RailsでWeb開発を行うための準備が完全に整いました。

1.3 最初のアプリケーション

コンピュータープログラミングにおける古来の伝統に従い、最初に作るアプリケーションは「Hello World」を表示するプログラムにしましょう。具体的には、Webページに「hello, world!」という文字列を表示するだけの単純なアプリケーションを、開発環境(1.3.4)と本番環境(1.5)でそれぞれ作成します。

どんなRailsアプリケーションも最初の作成手順は基本的に同じです。rails newコマンドを実行して作成します。このコマンドを実行するだけで、指定のディレクトリにRailsアプリケーションのスケルトンを簡単に作成できます。1.2.1で推奨しているCloud9 IDEを利用しない場合は、Railsプロジェクトで使うためのenvironmentディレクトリを作成しておいてください(リスト 1.5)。11

リスト 1.5: Railsプロジェクト用のenvironmentディレクトリを作る
# クラウドIDEではこの手順は不要です
$ cd                    # プロジェクトのホームディレクトリに移動
$ mkdir environment     # environmentディレクトリを作成
$ cd environment/       # 作成したenvironmentディレクトリに移動

リスト 1.5ではUnixのcdコマンドとmkdirコマンドを使います。こうしたコマンドが分からない方は、コラム 1.3をご覧ください。

コラム 1.3. 急いで学びたい人のためのUnixコマンドライン講座

WindowsユーザーやmacOSユーザーの多くはコマンドラインというものに馴染みがないことでしょう(macOSユーザーの方がほんのわずかコマンドラインを知っている人は多いかもしれませんが)。幸い、今はオススメのクラウド開発環境のおかげでUnixコマンドラインをみな同じように扱うことができ、Bashなどの標準的なシェルコマンドラインインターフェイスを実行できます12

コマンドラインの基本的な仕組みは本当にシンプルです。ユーザーはコマンドを発行(issue)することで、実にさまざまな操作を実行できます。ディレクトリの作成ならmkdirコマンド、ファイルの移動やリネームはmvコマンド、ファイルのコピーならcpコマンド、ファイルシステム内でのディレクトリの移動はcdコマンド、という具合です。GUI(グラフィカルユーザーインターフェイス)しか使ったことのないユーザーからすると、コマンドラインの黒い画面は何やら恐ろしげでとっつきが悪いように見えるかもしれませんが、見た目ほど当てにならないものはありません。コマンドラインはそれ自体が強力なツールであり、エンジニアにとってなくてはならない道具箱なのです13。そうでなければ、どうしてエンジニアが揃いも揃ってコマンドラインを使うでしょうか。経験豊富な開発者のデスクトップ画面を覗きこめば、十中八九どころか99%は、黒いターミナルウィンドウがいくつも開き、そこで多数のコマンドラインシェルが忙しく実行されているはずです。

コマンドラインについて話しだすときりがないので深入りはしませんが、本チュートリアルで必要なUnixコマンドラインのコマンドはほんのわずかしかありませんのでご安心ください(表 1.1)。Unixの基本的なコマンドラインについてもっと知りたい方は、コマンドライン編をぜひお読みください。

説明 コマンド コマンド例
ディレクトリ内容の表示 ls $ ls -l
ディレクトリの作成 mkdir <ディレクトリ名> $ mkdir environment
ディレクトリの移動 cd <ディレクトリ名> $ cd environment/
上のディレクトリに移動 $ cd ..
ホームディレクトリに移動 $ cd ~ もしくは $ cd
ホームディレクトリ直下のenvironmentに移動 $ cd ~/environment/
ファイルの移動やリネーム mv <移動元> <移動先> $ mv foo bar
mv <現在の名前> <変更後の名前>
ファイルのコピー cp <コピー元> <コピー先> $ cp foo bar
ファイルの削除 rm <ファイル名> $ rm foo
空のディレクトリの削除 rmdir <ディレクトリ名> $ rmdir environment/
中身のあるディレクトリの削除 rm -rf <ディレクトリ名> $ rm -rf tmp/
ファイルの内容の結合と表示 cat <ファイル名> $ cat ~/.ssh/id_rsa.pub
表 1.1: 主要なUnixコマンド

ローカルシステムまたはクラウドIDEで行う次の手順は、リスト 1.6のコマンドを使った最初のアプリケーションの作成です。リスト 1.6のコマンドでは、Railsのバージョンを明示的に指定している点にご注目ください。このようにバージョンを指定することで、リスト 1.2と同じバージョンのRailsで、最初のアプリケーションと同じファイル構造を作成することができます。

リスト 1.6: rails newを実行する(バージョン番号を指定)
$ cd ~/environment
$ rails _6.0.4_ new hello_app
      create
      create  README.md
      create  Rakefile
      create  .ruby-version
      create  config.ru
      create  .gitignore
      create  Gemfile
         run  git init from "."
Initialized empty Git repository in /home/ubuntu/environment/hello_app/.git/
      create  package.json
      create  app
      create  app/assets/config/manifest.js
      create  app/assets/stylesheets/application.css
      create  app/channels/application_cable/channel.rb
      create  app/channels/application_cable/connection.rb
      create  app/controllers/application_controller.rb
      create  app/helpers/application_helper.rb
      .
      .
      .

ご覧のとおり、railsコマンドを実行すると大量のファイルとディレクトリが作成されます。Webアプリケーションのディレクトリをどう構成するかは本来自由なのですが、RailsのようなWebフレームワークではディレクトリとファイルの構造(図 1.13)はこのように標準化されています。ファイル/ディレクトリ構造がすべてのRailsアプリで標準化されているおかげで、他の開発者の書いたRailsのコードが読みやすくなります。これはWebフレームワークを導入する大きなメリットです。

Railsで使われるデフォルトのファイルについては表 1.2をご覧ください。これらのファイルやディレクトリの意味や目的については本書全体に渡って説明いたします。特に5.2.1以降では、Rails 3.1から搭載されたアセットパイプラインの一部であるapp/assetsディレクトリについて、詳しく説明します。アセットパイプラインによって、CSS(Cascading Style Sheet)や画像ファイルなどのアセット(資産)を簡単に編成することもデプロイすることもできます。

6
図 1.13: 新規作成されたRailsアプリケーションのディレクトリ構造
ディレクトリ 用途
app/ モデル、ビュー、コントローラ、ヘルパーなどを含む主要なアプリケーションコード
app/assets アプリケーションで使うCSS(Cascading Style Sheet)、JavaScriptファイル、画像などのアセット
bin/ バイナリ実行可能ファイル
config/ アプリケーションの設定
db/ データベース関連のファイル
doc/ マニュアルなど、アプリケーションのドキュメント
lib/ ライブラリやモジュール置き場
log/ アプリケーションのログファイル
public/ エラーページなど、一般(Webブラウザなど)に直接公開するデータ
bin/rails コード生成、コンソールの起動、ローカルのWebサーバーの立ち上げなどで使うRailsスクリプト
test/ アプリケーションのテスト
tmp/ 一時ファイル
README.md アプリケーションの簡単な説明
Gemfile このアプリケーションに必要なGemの定義ファイル
Gemfile.lock アプリケーションで使われるgemのバージョンを確認するためのリスト
config.ru Rackミドルウェア用の設定ファイル
.gitignore Gitに取り込みたくないファイルを指定するためのパターン
表 1.2: デフォルトのRailsディレクトリ構成の概要

1.3.1 Bundler

Railsアプリケーションを新規作成したら、次はBundlerを実行して、アプリケーションに必要なgemをインストールします。Bundlerはrailsコマンド(リスト1.6)によって自動的に実行(この場合はbundle install)されます。ここではデフォルトのアプリケーションgemを変更してBundlerを再度実行してみます。そのために、テキストエディタでGemfileを開きます(クラウドIDEの場合は、ファイルナビゲーターで矢印をクリックしてサンプルアプリのディレクトリを開き、Gemfileアイコンをダブルクリックします)。Gemfileの内容は、だいたい図 1.14リスト 1.7のようになります。バージョン番号など細かな点で多少の違いがあるかもしれません。Gemfileの内容はRubyのコードですが、ここでは文法を気にする必要はありません。Rubyの詳細については4で説明します。ファイルやディレクトリが図 1.14のように表示されない場合、ナビゲーターの歯車アイコンをクリックして[Refresh File Tree]を選択します。

一般に、ファイルやディレクトリがうまく表示されていない場合はこのようにファイルツリーを再表示してみてください14

6
図 1.14: テキストエディタでデフォルトのGemfileを開く
リスト 1.7: hello_appディレクトリにあるデフォルトのGemfile Gemfile
source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }

ruby '2.7.6'

# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '~> 6.0.4'
# Use sqlite3 as the database for Active Record
gem 'sqlite3', '~> 1.4'
# Use Puma as the app server
gem 'puma', '~> 3.11'
# Use SCSS for stylesheets
gem 'sass-rails', '~> 5'
# Transpile app-like JavaScript. Read more: https://github.com/rails/webpacker
gem 'webpacker', '~> 4.0'
# Turbolinks makes navigating your web application faster.
# Read more: https://github.com/turbolinks/turbolinks
gem 'turbolinks', '~> 5'
# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
gem 'jbuilder', '~> 2.7'
# Use Redis adapter to run Action Cable in production
# gem 'redis', '~> 4.0'
# Use Active Model has_secure_password
# gem 'bcrypt', '~> 3.1.7'

# Use Active Storage variant
# gem 'image_processing', '~> 1.2'

# Reduces boot times through caching; required in config/boot.rb
gem 'bootsnap', '>= 1.4.2', require: false

group :development, :test do
  # Call 'byebug' anywhere in the code to stop execution and get a
  # debugger console
  gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
end

group :development do
  # Access an interactive console on exception pages or by calling 'console'
  # anywhere in the code.
  gem 'web-console', '>= 3.3.0'
  gem 'listen', '>= 3.0.5', '< 3.2'
  # Spring speeds up development by keeping your application running in the
  # background. Read more: https://github.com/rails/spring
  gem 'spring'
  gem 'spring-watcher-listen', '~> 2.0.0'
end

group :test do
  # Adds support for Capybara system testing and selenium driver
  gem 'capybara', '>= 2.15'
  gem 'selenium-webdriver'
  # Easy installation and use of web drivers to run system tests with browsers
  gem 'webdrivers'
end

# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]

Railsは常に進化し続けるため、ここでGemfileの内容が違っていたりRailsのバージョンが6.0.4となっていなくても大丈夫です。後述するGemfileでバージョンを明示的に固定するので、その変更を加えた後でbundle updateを実行すれば本書と同じバージョンになります。

ほとんどの行はハッシュシンボル #4.2)でコメントされています。これらの行では、よく使われているgemとBundlerの文法の例をコメント形式で紹介しています。この時点では、デフォルト以外のgemをインストールする必要はありません。

gemコマンドで特定のバージョン番号を指定しない限り、Bundlerは自動的に最新バージョンのgemを取得してインストールします。例えば、Gemfileに次のような記述があるとします。

gem 'sqlite3'

このsqlite3というgemのバージョンを指定する主な方法は2通りあります。これにより、Railsで使われるgemのバージョンを「ある程度」制御できます。1番目の方法は次のとおりです。

gem 'capybara', '>= 2.15'

最新バージョンのcapybara gemがインストールされます(これはテストで使うgemです)。極端に言えば、バージョンが7.2であっても、2.15と同じかそれより上のバージョンならインストールされます 。

2番目の方法は次のとおりです。

gem 'rails', '~> 6.0.1'

このように指定すると、rails gemのバージョンが6.0.1以上であり、かつ6.1より小さい場合にインストールされます。つまり、>=という記法では最新のgemを探してインストールし、~> 6.0.2という記法では細かな単位で更新可能なgemを探してインストールします(例: 6.0.46.0.5などの新しいバージョンがあればインストールされますが、6.1.0はインストールされません)15

残念ながら、経験上ちょっとしたマイナーアップグレードですら問題を引き起こすことがあります。このため、Railsチュートリアルでは基本的に事実上すべてのgemでバージョンを「ピンポイントで」指定し、がっちり固定してあります。ベテラン開発者にはGemfile~>を使って指定し、最新のgemを使って進めることをオススメしていますが、チュートリアルが思い通りに動かなくなる可能性があることはご承知おきください。

リスト 1.7Gemfileを、実際に使用する正確なバージョンのgemに置き換えたものをリスト 1.8に示します16

なお、この置換えのついでに、sqlite3 gemをdevelopment環境とtest環境(7.1.1)だけで使う(つまりproduction環境では使わない)ように変更している点にもご注目ください。これは、後でHerokuで使うデータベースと競合する可能性を防ぐための処置です(1.5)。

電子書籍版を読んでいる方へ】本書のGemfileで固定した各gemのバージョンは公式リポジトリと一致している必要があります。現在の章に合わせてご参照ください。
リスト 1.8: Gemfileの内容を一新させる Gemfile
source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }

ruby '2.7.6'

gem 'rails',      '6.0.4'
gem 'puma',       '4.3.6'
gem 'sass-rails', '5.1.0'
gem 'webpacker',  '4.0.7'
gem 'turbolinks', '5.2.0'
gem 'jbuilder',   '2.9.1'
gem 'bootsnap',   '1.10.3', require: false

group :development, :test do
  gem 'sqlite3', '1.4.2'
  gem 'byebug',  '11.0.1', platforms: [:mri, :mingw, :x64_mingw]
end

group :development do
  gem 'web-console',           '4.0.1'
  gem 'listen',                '3.1.5'
  gem 'spring',                '2.1.0'
  gem 'spring-watcher-listen', '2.0.1'
end

group :test do
  gem 'capybara',           '3.28.0'
  gem 'selenium-webdriver', '3.142.4'
  gem 'webdrivers',         '4.1.2'
end

# Windows ではタイムゾーン情報用の tzinfo-data gem を含める必要があります
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]

アプリケーションのGemfileの内容をリスト 1.8で置き換えたら、bundle installを実行してgemをインストールします17

$ cd hello_app/
$ bundle _2.2.17_ install
Fetching source index for https://rubygems.org/
.
.
.

bundle installコマンドの実行にはしばらく時間がかかるかもしれません。完了後、アプリケーションが実行可能になります。

ちなみに、bundle installを実行すると「まずbundle updateを実行してください」というようなメッセージが表示される場合があります。その場合は、メッセージのとおりにbundle updateをまず実行しましょう(マニュアルどおりに行かない場合に慌てず落ち着いて対応することもスキルの1つです。こうしたエラーメッセージにはその場で問題を解決する方法が含まれているものなので、よく読んでおきましょう)。

最後に、1.2.2でセットアップしたYarnを使ってWebpackerをインストールして完了です。Webpackerの使い方は5で説明します。

$ rails webpacker:install

1.3.2 rails server

1.3rails newコマンドと1.3.1bundle installコマンドを実行したことにより、実際に動かすことのできるアプリケーションが作成されました。ありがたいことに、Railsには開発マシンでのみブラウズできるローカルWebサーバーを起動するためのコマンドラインプログラム(スクリプト)が付属しているので、rails serverというコマンドを実行するだけでRailsアプリケーションを簡単に起動することができます。

システムによっては(クラウドIDEであっても)、rails serverコマンドを実行する前にローカルWebサーバーへの接続を許可する必要が生じることがあります。これを行うには、config/environments/development.rbファイルを開いてリスト 1.9図 1.15に示した2行を追加します。

リスト 1.9: ローカルWebサーバーへの接続を許可する config/environments/development.rb
Rails.application.configure do
  .
  .
  .
  # Cloud9 への接続を許可する
  config.hosts.clear
end
6
図 1.15: Cloud9でのRailsサーバーへの接続を許可する

なお、リスト 1.10に表示されているこのrails serverコマンドは、ターミナルタブをもうひとつ開いてそこで実行することをオススメします。そうすることで、最初のタブで引き続きコマンドを実行できるので便利です(図 1.16図 1.17)。リスト 1.10で「Ctrl-C」キー18を押すことでサーバーをシャットダウンできます。

リスト 1.10: Railsサーバーを実行する
$ cd ~/environment/hello_app/
$ rails server
=> Booting Puma
=> Ctrl-C to shutdown server
6
図 1.16: 新しくターミナルを開く
6
図 1.17: Railsサーバーを別のタブで実行する

(クラウドでない)OSでrails serverの結果を表示するには、ブラウザのアドレスバーにhttp://localhost:3000を貼り付けてください。クラウドIDEの場合は、Previewを開いて[Preview Running Application]をクリックして(図 1.18)ブラウザのウィンドウかタブで表示します(図 1.19)。いずれの場合も、図 1.20のように表示されるはずです。

6
図 1.18: クラウドワークスペース上で実行するローカルサーバーを共有する
6
図 1.19: 実行中のアプリをブラウザウィンドウやタブで開く
6
図 1.20: rails serverを実行したときのデフォルトのRailsページ

演習

Railsチュートリアルには多くの演習問題が含まれています。チュートリアルを学びながらこれらの演習を解くことを強くオススメします。

本編と演習問題を分けて扱うため、原則として演習問題の解答はその後の本編コードリストで使わないようにしています。つまり、演習の解答を自分のコードに反映していくうちに、コードがチュートリアルから少しずつずれる可能性もあるということです。このようなずれを自力で解決することは、「熟練」にとても役立つ学びとなります(コラム 1.2)。

用意されている問題の多くはそう簡単に解けませんが、まだ最初なのでウォーミングアップとしてやさしい演習から始めることにしましょう。

  1. デフォルトのRailsページに表示されているものと比べて、今の自分のコンピュータにあるRubyのバージョンはいくつになっていますか? コマンドラインでruby -vを実行することで簡単に確認できます。
  2. 同様にして、Railsのバージョンも調べてみましょう。調べたバージョンはリスト 1.2でインストールしたバージョンと一致しているでしょうか?

1.3.3 Model-View-Controller(MVC)

まだ始まったばかりですが、今のうちにRailsアプリケーションの全体的な仕組みを知っておくと後々役立ちます(図 1.21)。デフォルトのRailsアプリ構造(図  1.13)を眺めてみると、app/というディレクトリがあり、その中に「models」「views」「controllers」という3つのサブディレクトリがあることに気付いた方もいると思います。ここにはRailsがMVC(model-view-controller)というアーキテクチャパターンを採用していることが暗に示されています。MVCでは、アプリケーション内のデータ(ユーザー情報など)と、データを表示するコードを分離します。アプリケーションのグラフィカルユーザーインターフェイス(GUI)は多くの場合このようにして構成されます。

ブラウザがRailsアプリと通信する際、一般的にWebサーバーにリクエスト(request)を送信し、これはリクエストを処理する役割を担っているRailsのコントローラ(controller)に渡されます。コントローラは、場合によってはすぐにビュー(view)を生成してHTMLをブラウザに送り返します。動的なサイトでは、一般にコントローラは(ユーザーなどの)サイトの要素を表しており、データベースとの通信を担当しているRubyのオブジェクトであるモデル(model) と対話します。モデルを呼び出した後、コントローラは、ビューを描画し、完成したWebページをHTMLとしてブラウザに返します。

6
図 1.21: Model-View-Controller(MVC)アーキテクチャの概念図

今はこの解説がまだ少し抽象的に思えるかもしれませんが、この章は後に何度も参照しますのでご安心ください。特に1.3.4では、MVCを扱うお試しアプリケーションをご覧に入れます。2.2.2では、このtoyアプリを使ってMVCの詳細を解説します。サンプルアプリケーションでは、MVCの3つの要素をすべて扱います。3.2でまずコントローラとビューを扱い、モデルは6.1から扱い始めます。7.1.2では、3つの要素が協調して動作します。

1.3.4 Hello, world!

記念すべき最初のMVCフレームワークアプリケーションとして、先ほど作ったアプリにほんのちょっぴり変更を加えることにしましょう。「hello, world!」という文字列を表示するだけのコントローラのアクションを追加し、図 1.20のデフォルトRailsページを置き換えてみましょう(コントローラのアクションについては2.2.2で詳しく解説します)。

コントローラという名前からご想像のとおり、コントローラのアクションはコントローラ内で定義します。ここでは、Applicationという名前のコントローラの中にhelloという名前のアクションを作成することにします。実際、この時点ではコントローラはApplicationひとつしかありません。次のコマンドを実行すると、現在あるコントローラを確認できます。

$ ls app/controllers/*_controller.rb

新しいコントローラの作成は2で行います。リスト 1.11に、helloを定義したところを示します。ここではrenderメソッドで「hello, world!」というテキストを表示しています。この時点ではRubyの文法については気にする必要はありません。4で詳しく解説します。

リスト 1.11: Applicationコントローラにhelloを追加する app/controllers/application_controller.rb
class ApplicationController < ActionController::Base

  def hello
    render html: "hello, world!"
  end
end

表示したい文字列を返すアクションを定義したので、今度はデフォルトのページ(図 1.20)の代わりにこのアクションを使うようRailsに指示します。そのためには、Railsのルーター(router)を編集します。ルーターはコントローラとブラウザの間に配置され(図 1.21)、ブラウザからのリクエストをコントローラに振り分ける(=ルーティング)役割を果たします(図 1.21は簡単のためルーターを省略していますが、2.2.2で詳しく解説します)。ここではデフォルトのページを差し替えたいので、ルートのルーティングルート URLにアクセスした場合のルーティング)を変更することにします。例えば http://www.example.com/ というURLの末尾は「/」になっているので、ルートURLは単に「/」(スラッシュ)と簡略表記することもあります(訳注: 本チュートリアルではrouteやroutingを「ルーティング」、rootを「ルート」と表記します)。

Railsのルーティングファイル(config/routes.rb)にはRailsガイドの「ルーティング」を参照するようコメントがあり、ルートルーティングの構成方法がリンク先に示されています(リスト 1.12)。具体的なルーティングの文法は、次のような形式になります。

root 'controller_name#action_name'

上のコードの場合、コントローラ名はapplicationであり、アクション名は helloです。変更後のコードをリスト 1.13に示します。

リスト 1.12: デフォルトのルーティングファイル(見栄えのためフォーマットを若干修正) config/routes.rb
Rails.application.routes.draw do
  # For details on the DSL available within this file,
  # see https://guides.rubyonrails.org/routing.html
end
リスト 1.13: ルートルーティングを設定する config/routes.rb
Rails.application.routes.draw do
  root 'application#hello'
end

リスト 1.11のコードとリスト 1.13のコードを使うと、ルートルーティングから「hello, world!」が返されるようになります(図 1.2219

6
図 1.22: 「hello, world!」をブラウザで表示する

演習

  1. リスト 1.11helloアクションを書き換え、「hello, world!」の代わりに「hola, mundo!」と表示されるようにしてみましょう。
  2. Railsでは「非ASCII文字」もサポートされています。「¡Hola, mundo!」にはスペイン語特有の逆さ感嘆符「¡」が含まれています(図 1.2320。「¡」文字をMacで表示するには、Optionキーを押しながら1キーを押します。この文字をコピーして自分のエディタに貼り付ける方が早いかもしれません。
  3. リスト 1.11helloアクションを参考にして、2つ目のアクションgoodbyeを追加しましょう。このアクションは、「goodbye, world!」というテキストを表示します。リスト 1.13のルーティングを編集して、ルートルーティングの割り当て先をhelloアクションからgoodbyeアクションに変更します(図 1.24)。
6
図 1.23: ルートルーティングで「¡Hola, mundo!」を表示するよう変更する
6
図 1.24: ルートルーティングで「goodbye, world!」を表示するよう変更する

1.4 Gitによるバージョン管理

実際に動作するRailsアプリを初めて完成させることができましたので、さっそくアプリケーションのソースコードをバージョン管理下に置いてみましょう。「バージョン管理をしないとアプリケーションが動かない」ということはありませんが、ほとんどの開発現場において必要不可欠なものであると考えています。また、バージョン管理システムを導入しておけば、プロジェクトのコードの履歴を追ったり、うっかり削除してしまったファイルを復旧(ロールバック)したりという作業が行えるようになります。バージョン管理システムを熟知することは、今ではあらゆるソフトウェア開発者にとって必須のスキルであると言ってよいでしょう。

バージョン管理システムにもさまざまなものがありますが、Webアプリケーション開発ではリーナス・トーバルズLinuxカーネルのために開発した分散バージョン管理システム「Git」が主流になっています。Gitはそれだけで大きなテーマなので、すべてを説明しようとすると1冊の本を軽く超えてしまいます。本セクションではバージョン管理システムの基本について説明していきますが、詳しく知りたい方は Git/GitHub編をご覧ください。

ソースコードのバージョン管理システムは「何としても」導入してください。バージョン管理はRailsのどんな場面でも必要になりますし、バージョン管理システムを応用して、自分の作成したコードを他の開発者と簡単に共有したり(1.4.3)、最初の章で作成したアプリケーションを本番サーバーへデプロイしたりすることもできる(1.5)からです。

1.4.1 インストールとセットアップ

推奨環境であるクラウドIDE(1.2.1)にはデフォルトでGitが導入されていますので、追加で導入する必要はありません。何らかの理由で導入が必要な方はGit/GitHub編「Gitのインストールとセットアップ」などを参考に、Gitを導入してみてください。

初回のシステム・セットアップ

インストールしたGitを使う前に、最初に設定を行う必要があります。これは、コンピュータ1台につき1回だけ行います。

最初のステップは、自分の名前とメールアドレスを設定することです(リスト 1.14)。

リスト 1.14: 名前とメールをGitに設定する
$ git config --global user.name "自分のニックネームまたは名前など"
$ git config --global user.email your.name@example.com

ここで設定した名前やメールアドレスは、今後リポジトリ上で一般に公開されるためご注意ください。もし公開できるメールアドレスをお持ちでない場合は、第3者に悪影響を与えないことが保障されている@example.comをそのまま使うこともできます。

次に、Gitで使うデフォルトのエディタを設定します。後述する「Gitの編集(Edit)」などで使われます。ここでは、比較的使いやすくクラウドIDEのデフォルトエディタでもあるnanoエディタを使うことにしましょう。具体的には、リスト 1.15を実行してシンボリックリンクsymlinkとも呼ばれます)を作成して、nanoの実行ファイルを指定します(リスト 1.15のコマンドは初心者には少々難しいので、今読んで理解できなくても心配は不要です)。21

リスト 1.15: クラウドIDEでデフォルトのエディタを設定する
$ sudo ln -sf `which nano` /usr/bin

次のエイリアスalias)の設定は必須ではありませんが、checkoutコマンドを短く入力できるので設定しておくと便利です(リスト 1.16)。

リスト 1.16: git coをcheckoutのエイリアスに設定する
$ git config --global alias.co checkout

本チュートリアルでは、誰が入力しても動くように省略なしのgit checkoutで記述してありますが、実際の筆者はほぼ毎回git coと入力しています。

最後の手順は、pushコマンドやpullコマンドを入力するたびにパスワードを入力しなくて済むようにする設定です(1.4.4)。このオプションはシステムによって設定方法が若干異なるので、Linux環境以外をお使いの方は“Caching your GitHub password in Git”をご確認ください。クラウドIDEなどのLinux環境をお使いの方は、以下のようにcache timeoutを設定するだけで完了します(リスト 1.17)。

リスト 1.17: Gitでパスワードを一定時間保持するように設定する
$ git config --global credential.helper "cache --timeout=86400"

リスト 1.17を設定すると、Gitはパスワードを86,400秒(つまり1日)保持してくれます22。セキュリティに不安がある場合は、デフォルトのcache timeout設定である900秒(つまり15分)などの短い時間にしてもよいでしょう。

初回のリポジトリ・セットアップ

今度は、ソースコードの状態を保存する場所「リポジトリ」に対して必要なセットアップを進めていきます。今回の場合はhello_appの状態を保存したいので、以下のコマンドでhello_appのあるディレクトリ(ルートディレクトリと呼びます)に移動し、新しいリポジトリの初期化(git init)を実行します。

$ cd ~/environment/hello_app

$ git init
Reinitialized existing Git repository in
/home/ubuntu/environment/hello_app/.git/

リポジトリが「初期化された(Reinitialized)」というメッセージが表示されている点にご注目ください。つまり、これまでの操作で既に1度初期化を実行していたわけです。実は、Rails 6以降でrails newコマンド(リスト 1.6)を実行すると、Gitリポジトリも自動的に初期化してくれます。GitがWebアプリケーション開発の業界でどれほど定着しているかがよく分かる事例ですね。このためRailsアプリケーションの開発においては、git initを必ずしも実行する必要はないと言えます。しかしRails以外の開発でも同じとは限らないので、常にgit initを実行する癖をつけておくのはよいことです。

次はgit add -Aを実行して、プロジェクトの全ファイルをリポジトリに追加します23

$ git add -A

このコマンドを実行すると、Git管理下にあるすべての変更ファイルが追加されます。ただし、.gitignoreに書かれているパターンにマッチするはファイルは追加されません。.gitignoreファイルもrails newコマンド実行時に自動生成され、Railsでよく使うパターンが追加されています。もちろん、自分でパターンを追加しても構いません24

Gitで変更したファイルを追加するときは、最初ステージング(Staging)という一種のコミット待ち状態にします。安全のため、いきなり変更を保存(コミット)しないようになっているのです。現在のステージングの状態を知るにはgit statusコマンドを使います。

$ git status
On branch master

No commits yet

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)

        new file:   .browserslistrc
        new file:   .gitignore
        new file:   .ruby-version
        new file:   Gemfile
        new file:   Gemfile.lock
        .
        .
        .

ステージングに控えている変更をリポジトリに保存(コミット)するときは、git commitコマンドを使います。

$ git commit -m "Initialize repository"
[master (root-commit) df0a62f] Initialize repository
.
.
.

-mオプションを使うと、コミットメッセージをコマンドライン上で直接記入できます。-mオプションを使わない場合はデフォルトに設定されているエディタが開き、そこでコミットメッセージを入力します(本チュートリアルでは常に-mオプションを使っていきます)。

git commitで保存したコミットは、あくまでローカルマシン(Cloud9など)にしか保存されない点にご注意ください。ローカルマシンに保存したコミットを、GitHubやHerokuなどに置かれているGitリポジトリに反映(プッシュ)する方法については1.4.4で解説します。

ちなみに、git logコマンドでこれまでのコミットメッセージの履歴を確認することもできます。

$ git log
commit b981e5714e4d4a4f518aeca90270843c178b714e (HEAD -> master)
Author: Michael Hartl <michael@michaelhartl.com>
Date:   Sun Aug 18 17:57:06 2019 +0000

    Initialize repository

コミットログがある程度長い場合は、qキーを押して終了します。Git/GitHub編でも解説していますが、git logではlessコマンドをインターフェイスとして使っています。なお、lessコマンドの詳細は、コマンドライン編「使うならmoreよりless」で説明しています。

1.4.2 Gitのメリット

「ソースコードのバージョンをGitで管理する理由が分からない」という方もいるかもしれませんので、1つ例をご紹介します。仮に、あなたが重要なapp/controllers/ディレクトリを削除してしまったとしましょう(ホーマー・シンプソンがやらかすような感じで)。

$ ls app/controllers/
application_controller.rb  concerns/
$ rm -rf app/controllers/
$ ls app/controllers/
ls: app/controllers/: No such file or directory

ここでは、Unixコマンドのlsapp/controllers/ディレクトリの中身を表示した後、rmコマンドでうっかりディレクトリごと削除してしまったとします(表 1.1)。詳しくは コマンドライン編の「「ディレクトリのリネーム/コピー/削除を行う」で解説しますが、ここで使っている-rfオプションは、「recursive」(ディレクトリ内にあるすべてのファイルとサブディレクトリを削除する)と、「force」(削除して良いかどうかの確認・警告をせずに削除する)という意味になります。

現在の状態を確認してみましょう。

$ git status
On branch master
Changes not staged for commit:
  (use "git add/rm <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

        deleted:    app/controllers/application_controller.rb
        deleted:    app/controllers/concerns/.keep

no changes added to commit (use "git add" and/or "git commit -a")

ファイルがいくつか削除されましたが、この変更はまだステージングに追加されておらず、コミットもされていません。つまり、checkoutコマンド(と、現在までの変更を強制的に元に戻すための-fオプション)を使えば、直前にコミットした状態まで簡単に戻すことができます。

$ git checkout -f

$ git status
On branch master
nothing to commit, working tree clean

$ ls app/controllers/
application_controller.rb  concerns/

うっかり削除してしまったディレクトリやファイルが、無事に復旧できましたね。これがGitを使うメリットの1つです。

1.4.3 GitHub

Gitを使ったソースコードのバージョン管理ができるようになったので、今度はGitHubにソースコードをアップロードしてみましょう。GitHubは、Gitに特化したソフトウェア開発のプラットフォームです。ローカルマシンにあるGitリポジトリを、わざわざGitHubにプッシュする主な理由は2つあります。1つ目は、ソースコードとそのすべての変更履歴(コミット記録)の完全なバックアップを作成するためです。2つ目は、他の開発者との共同作業をより簡単に行うためです。

GitHubを始める方法は単純明快です。GitHubアカウントをお持ちでない方はGitHubアカウントに登録(サインアップ)しましょう(図 1.2525

6
図 1.25: GitHubにユーザー登録する

ユーザー登録が完了したら、+記号のドロップダウンメニューをクリックして“New repository”を選択します(図 1.26)。

6
図 1.26: “New repository”オプションを選択する

新しいリポジトリを作成するページが表示されたら、リポジトリ名にhello_app)を入力しましょう。Description(説明欄)の内容は空欄でも大丈夫です。そして万全の注意を払って、確実に、“Private”オプションを選択してください(1.27)。

Publicオプションを選択し、本チュートリアルで取り扱うRailsアプリのソースコードをうっかり公開しても原理的には安全です。とはいえ、特にGitを今回初めて使うような場合は秘密鍵のような重要なファイルをうっかりコミットしてしまう可能性もゼロではありません。ですから、何か起きる前にひとまずPrivateにしておく用心深さが大事です26

6
図 1.27: GitHubでPrivateリポジトリを作成する

“Create repository”ボタンをクリックすると、図 1.28のように既存のリポジトリをGitHubに追加するコマンドが表示されるはずです。ここではHTTPSオプションを選択してください。27

6
図 1.28: 既存のリポジトリを追加する

次にGitHubの公式ドキュメントに従って、リポジトリをプッシュする際に必要な個人アクセストークンを作成しましょう28。ドキュメントの通りに必要事項を入力していき、Expirationには個人アクセストークンの有効期限を入力します。

6
図 1.29: 有効期限は必要に応じて自由に設定できます

Select scopesでは個人アクセストークンに含める権限を設定します。本チュートリアルではrepoを追加してください。(各権限の詳細はGitHubの公式ドキュメントから確認できます)

6
図 1.30: トークンに含めたい権限にチェックを入れる

Generate tokenをクリックして発行される個人アクセストークンは、ページを閉じるか移動すると消えてしまうので、次のステップにあるgit pushが終わるまでページを開いたままにしておきましょう。また、ここで生成された個人アクセストークンは、パスワードと同じように重要な情報として扱ってください。

最後にリスト 1.18のコマンドを実行し、メッセージに従ってGitHubのユーザー名(Username)と、パスワード(Password)を入力します。パスワードの欄には、先ほど作成した個人アクセストークンを入力してください。無事に認証に成功したら、以後はリスト 1.17で設定したcache timeoutの期間か、もしくは個人アクセストークンの有効期限のどちらかが切れるまでパスワード入力は不要になります。

リスト 1.18: GitHubをリモートoriginに追加してそのリポジトリにpushする
$ git remote add origin https://github.com/<あなたのGitHubアカウント名>/hello_app.git
$ git push -u origin master

リスト 1.18にあるgit remoteコマンドは、GitHubに置いたGitリポジトリをプッシュ(push)先の1つとして登録するコマンドです。今回はoriginという名前で登録しています。次のgit pushコマンドでは、ローカルマシンにあるGitリポジトリを、先ほど登録したorigin(GitHub)にアップロードしています。29

なお、リスト 1.18<あなたのGitHubアカウント名>の部分は実際のユーザー名に置き換える必要があります。たとえば筆者(mhartl)の場合であれば、実行するコマンドは次のようになります。

$ git remote add origin https://github.com/mhartl/hello_app.git

このコマンドの実行が成功すると、hello_appリポジトリの内容がGitHub上でも確認できるようになります。このページではファイルの一覧やコミットの確認など、さまざまな機能を利用できます(図 1.31)。

6
図 1.31: GitHubのリポジトリページ

1.4.4 ブランチ、編集、コミット、マージ

1.4.3の手順に沿って進めた場合、READMEファイルの内容がGitHubリポジトリのページに表示されることに気付いたでしょうか(図 1.32)。このREADME.mdファイルは、リスト 1.6のコマンドを実行したときに自動生成されました。ファイル名の拡張子が「.md」となっているファイルは、Markdownという人間にとって読みやすい記法を使って書きます30。Markdownは簡単にHTMLに変換できるため、GitHubでもMarkdownで書かれたREADME.mdファイルをHTMLで表示してくれます。

Railsが自動生成したREADMEをそのまま使ってもよいですし、プロジェクトに合わせて内容を書き換えても構いません。とはいえ良い練習になるので、今回はREADMEを書き換えながらGitの使い方に慣れてみましょう。具体的には、Gitの基本的なコマンドであるブランチ(branch)、編集(edit)、コミット(commit)、マージ(merge)の4つを紹介します31

6
図 1.32: GitHubのデフォルトRails READMEの表示

Gitのブランチ(Branch)

Gitはブランチ(branch)を簡単かつ高速に作成できます。ブランチとは基本的にはコード全体のコピーで、元のコードにいつでも戻れる状態を維持しながら、新しくコードを追加したり変更したいときに便利です。通常、大元のコードがあるブランチはmasterブランチと呼ばれ、ブランチを新たに作りたいときはcheckout-bオプションで作成できます。

$ git checkout -b modify-README
Switched to a new branch 'modify-README'

$ git branch
  master
* modify-README

2つ目のコマンド(git branch)は、ローカルブランチの一覧を表示します。「*」は現在使用中のブランチを表しています。1つ目のgit checkout -b modify-READMEコマンドで、新しいブランチの作成と、そのブランチへの切り替えが同時に行われている点にご注目ください。modify-READMEブランチに「*」が付いているので、現在はmodify-READMEブランチにいることが分かります。(以後、このような新たに作成したブランチを本書ではトピックブランチと呼びます)

トピックブランチは他の開発者と共同作業するときにその真価を発揮しますが32、本チュートリアルのように1人で作業するときでも有用です。modify-READMEブランチで行った変更はmasterブランチに影響しないため、たとえば試行錯誤を繰り返してコードがめちゃくちゃになってしまってもmasterブランチに戻れればいつでも元の状態に戻せますし、もしもう一度書き直したい場合はmodify-READMEブランチごと削除することもできます(具体的な方法は本章の最後で説明します)。

ちなみに、READMEのような小さな変更をするときはブランチを作成せずに直接コミットすることもできます。とはいえ「良い習慣を身につけるのは早ければ早いほど良い」ので、今のうちにブランチを使ったコミットの練習もしておきましょう。

コラム 1.4. GitHubのデフォルトブランチ名について

2020年10月、GitHubからアナウンスがありました。それは新規作成されるリポジトリのデフォルトのブランチ名が、従来のmasterからmainに変更されたというものです。デフォルトブランチ名が変更された理由についてはWikipediaに譲りますが、masterもまだ広く使われているため、皆さんが今後ドキュメントや書籍などでmasterというブランチ名を見かけることもあるかもしれません。その場合は適宜mainに読み替えて理解すると良いでしょう。詳しくはブログ記事「Default Git Branch Name with Learn Enough and the Rails Tutorial(英語)」をご参照ください。

Gitの編集(Edit)

トピックブランチを作ったら、READMEを編集(edit)してコンテンツを追加しましょう(リスト 1.19図 1.33)。

リスト 1.19: 新しいREADMEファイル README.md
# Ruby on Rails Tutorial

## "hello, world!"

This is the first application for the
[*Ruby on Rails Tutorial*](https://railstutorial.jp/)
by [Michael Hartl](https://www.michaelhartl.com/). Hello, world!
6
図 1.33: READMEファイルを編集する

Gitのコミット(Commit)

変更が終わったら、git statusコマンドで現在の状態を確認してみましょう。

$ git status
On branch modify-README
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

        modified:   README.md

no changes added to commit (use "git add" and/or "git commit -a")

この時点で1.4.1.2と同じようにgit add -Aと実行することもできますが、git commitにはすべての変更ファイル(git mvで作成したファイルも含む)をまとめてコミットする-aオプションもあります。このオプションを使うと、以下のようにコミットすることもできます。

$ git commit -a -m "Improve the README file"
[modify-README 34bb6a5] Improve the README file
 1 file changed, 5 insertions(+), 22 deletions(-)

ただしgit commit -agit add -Aでは、意図していないファイルを誤ってコミットしてしまう可能性もあるため注意が必要です。不安な場合は、git add READMEgit add .のように追加するファイル名またはディレクトリ名を指定し、git statusで対象ファイルを確認後、git commitでコミットしましょう。

git commitのコミットメッセージを英語で書く場合は現在形かつ命令形で書くようにしましょう33。というのも、コミットメッセージではそのコミットが「何をした」のかを書くよりも、「何をする」ためのものなのかを書く方が後から見返したときに分かりやすくなるからです。さらに、現在形かつ命令形で書いておけば、Git自身が自動的に生成するコミットメッセージ(例えば Merge pull request #123 ... など)とも時制が一致します。詳しくは Git/GitHub編「Gitにコミットするとは」をご覧ください。

Gitのマージ(Merge)

ファイルの変更をコミットし終えたら、masterブランチにこの変更をマージ(merge)します。

$ git checkout master
Switched to branch 'master'

$ git merge modify-README
Updating b981e57..015008c
Fast-forward
 README.md | 27 +++++----------------------
 1 file changed, 5 insertions(+), 22 deletions(-)

上の例では015008cと表示されていますが、これはGitが生成するランダムな文字列(ハッシュ)のため、一致しなくても大丈夫です。ハッシュの値は環境によって多少異なりますが、他の部分はほとんど同じように表示されるはずです。

変更をマージした後は、git branch -dを実行してトピックブランチを削除しましょう。

$ git branch -d modify-README
Deleted branch modify-README (was 015008c).

なお、トピックブランチの削除は必須ではありません。実際、トピックブランチを削除せず、そのままにしておくケースもあります。トピックブランチを削除せずに残しておけば、トピックブランチとmasterブランチを交互に行き来して、キリの良い所で変更をマージすることもできます。

最後に、git branch-Dオプションを使った、マージ前のトピックブランチを破棄する方法も紹介します。

# これはあくまで例です。誤ってブランチを作ったとき以外は実行しないでください。
$ git checkout -b topic-branch
$ <ココで何か変更を加えてみてください>
$ git add -A
$ git commit -a -m "Make major mistake"
$ git checkout master
$ git branch -D topic-branch

-dオプションと異なり、-Dオプションは変更をマージしていなくてもブランチを削除できます。

Gitのプッシュ(Push)

ローカルマシン上のREADMEファイルの更新が終わったので、プッシュ(push)コマンドでGitHubに変更をアップロードしてみましょう。既に1.4.3で一度プッシュしているため、今回はgit push origin masterを省略したgit pushでも実行できるはずです。

$ git push

無事にアップロードできたら、GitHub上にあるhello_appのページを確認してみましょう。README.mdの部分が更新されていれば成功です(図 1.34)。

6
図 1.34: GitHub上の更新したREADMEファイル

1.5 デプロイする

まだ第1章の途中ですが、1.4でバージョン管理システム(Git)の設定が完了しているため、この時点でRailsアプリのソースコードを本番環境にアップロードし、動かすことができます。本書では、この一連の作業を以後「デプロイ」と呼びます。

技術的にはこの時点でのデプロイは必須ではありませんが、継続的にデプロイすることで問題を早い段階で見つけるメリットがあります。例えば開発環境のテストを繰り返すばかりで、いつまでも本番環境にデプロイしないままだと、アプリケーションを公開するギリギリになって思わぬ事態に遭遇する可能性が高まります34

かつてはRailsアプリを本番環境にデプロイする作業は大変でしたが、ここ数年で急速に簡単になりました。国内大手のSAKURA internetではレンタルサーバーやVPSなどで簡単に借りれますし、一通りのデプロイ環境を一気通貫して提供するRenderHerokuなども便利です。

筆者のお気に入りはHerokuで、これはさまざまなWebアプリケーションの本番環境として使えるプラットフォームです(既にご存知かもしれませんがHeroku自身もRailsで構築されています)。Herokuはソースコードのバージョン管理にGitを使っていれば、Railsアプリケーションを簡単に本番環境にデプロイできます。本書でGitを導入したのは、まさにこのHerokuを使うためでもあります(まだGitの設定をしていない方は1.4を参照してください)。加えてHerokuの無料プランには、本チュートリアルを進める上で十分過ぎるほどの機能が備わっています。

このセクションでは、最初のRailsアプリケーションをHerokuにデプロイします。作業内容の一部に少し高度な部分も含まれていますが、すべてを理解できなくても大丈夫なのでご安心ください。今大事なのは、このセクションの終わりまで手順を進め、作成したアプリケーションをデプロイする流れを体験することです。

1.5.1 Herokuのセットアップとデプロイ

HerokuではPostgreSQLというデータベースを使います(ちなみに発音は “post-gres-cue-ell” で、よく“Postgres”と略されます)。そのため本番環境(production)にデプロイするためには、まずpg gemをGemfileに追加して、RailsアプリケーションがPostgreSQLデータベースと通信できるようにします。

group :production do
  gem 'pg', '1.1.4'
end

Railsアプリケーションの開発環境(development)ではSQLiteというデータベースを使っていますが、SQLiteはHerokuでは使えないため、sqlite3 gemが本番環境に導入されないGemfileを変更します35。(リスト 1.8

group :development, :test do
  gem 'sqlite3', '1.4.2'
  gem 'byebug',  '11.0.1', platforms: [:mri, :mingw, :x64_mingw]
end

最終的なGemfileリスト 1.20のようになります。

電子書籍版を読んでいる方へ】本書のGemfileで固定した各gemのバージョンは公式リポジトリと一致している必要があります。現在の章に合わせてご参照ください。
リスト 1.20: 追加や並び替えを行ったGemfile Gemfile
source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }

ruby '2.7.6'

gem 'rails',      '6.0.4'
gem 'puma',       '4.3.6'
gem 'sass-rails', '5.1.0'
gem 'webpacker',  '4.0.7'
gem 'turbolinks', '5.2.0'
gem 'jbuilder',   '2.9.1'
gem 'bootsnap',   '1.10.3', require: false

group :development, :test do
  gem 'sqlite3', '1.4.2'
  gem 'byebug',  '11.0.1', platforms: [:mri, :mingw, :x64_mingw]
end

group :development do
  gem 'web-console',           '4.0.1'
  gem 'listen',                '3.1.5'
  gem 'spring',                '2.1.0'
  gem 'spring-watcher-listen', '2.0.1'
end

group :test do
  gem 'capybara',           '3.28.0'
  gem 'selenium-webdriver', '3.142.4'
  gem 'webdrivers',         '4.1.2'
end

group :production do
  gem 'pg', '1.1.4'
end

# Windows ではタイムゾーン情報用の tzinfo-data gem を含める必要があります
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]

本番環境でのみ使うpg gemを開発環境(Cloud9などの開発用マシン)にインストールしないようにするため、bundle configコマンドを使って、本番環境でしか使わないgemは開発環境にインストールしないよう設定することができます。(リスト 1.21)。

リスト 1.21: 本番環境用以外のgemをインストールする
$ bundle _2.2.17_ config set --local without 'production'
$ bundle _2.2.17_ install

上の設定を行わないと、pg gemのインストールで失敗することがあります。しかしリスト 1.20で追加したpg gemは本番環境でしか使わないため、開発環境でスキップしてもデプロイは可能です。36

最後に、リスト 1.21を実行した結果をコミットしましょう。無事にコマンドが実行できると、Gemfilepg gemを追加した結果が、Gemfile.lockに反映させるはずです。本番環境ではGemfileだけではなくGemfile.lockの内容も必要になるため、これから行う本番環境へのデプロイを成功させるために、変更結果を忘れずにコミッしておきましょう。

$ git commit -a -m "Update Gemfile for Heroku"

次のステップは、Herokuアカウントの作成と設定です。まずはHerokuのユーザー登録を行います。続いて、自分の開発マシンにherokuコマンドがインストールされているかどうかを確認します。

$ heroku --version

Herokuがインストールされていると、バージョン番号とともにherokuのコマンドラインインターフェース(Command Line Interface: CLI)が利用可能であるというメッセージが表示されます。ただしほとんどの場合は最初からインストールされていないので、The Heroku CLIからインストールする必要があります。クラウドIDEを使っている場合は、リスト 1.22のコマンドを実行することでHeroku CLIをインストールできます。

リスト 1.22: クラウドIDE上でHerokuをインストールするコマンド
$ source <(curl -sL https://cdn.learnenough.com/heroku_install)

リスト 1.22のコマンドでインストールできたかどうかは、次のコマンドで確認することができます。正しくインストールできていれば、バージョン番号が表示されるようになります(バージョン番号は異なっていても大丈夫です)。

$ heroku --version
heroku/7.27.1 linux-x64 node-v11.14.0

Herokuのコマンドラインインターフェイス(CLI)がインストールされていることが確認できたら、いよいよherokuコマンドで、Herokuユーザー登録時に使ったメールアドレスとパスワードを入力してログインします(なお--interactiveオプションを使うと、herokuコマンドでブラウザを開かないようにできます)。

$ heroku login --interactive

Herokuで多要素認証(MFA)を有効にしている場合は、ここでパスワードを入力してもログインできません。MFAを有効にしている場合はHerokuダッシュボードの「Authorizations」からトークンを発行し、そのトークンをパスワード欄に入力してください。

最後にheroku createコマンドを実行して、Heroku上にアプリケーションを実行する場所(本番環境)を作成します(リスト 1.23)。

リスト 1.23: Heroku上に本番環境を作成する
$ heroku create
Creating app... done, blooming-bayou-75897
https://blooming-bayou-75897.herokuapp.com/ |
https://git.heroku.com/blooming-bayou-75897.git

$ heroku stack:set heroku-20
Setting stack to heroku-20... done

Heroku上の本番環境も日々変化していますが、本チュートリアルでは学習のしやすさを重視し、バージョンをHeroku-20 Stackに固定しています。なお最終章ではRubyや各種ライブラリのバージョンを最新に上げる演習も用意しています。

このheroku createコマンドを実行すると本番環境用のURLが自動的に作成され、さっそくブラウザからそのURLにアクセスするともできます。ソースコードをHerokuにまだアップロードしていないため(git push heroku masterを実行していないため)、今は何も表示されなくても大丈夫です。次のステップでRailsアプリケーションをデプロイし、Webページを表示させてみましょう。

1.5.2 Herokuにデプロイする(1)

Railsアプリケーションを実際にHerokuにデプロイするには、まずGitを使ってHerokuにリポジトリをプッシュします。

$ git push heroku master

Cloud9以外の開発環境で進めている場合、デプロイで失敗することがあります。まずは落ち着き、ゆっくりとエラーメッセージを読み解いていきましょう。エラーメッセージは頼りになる味方です。例えばもしbundler関連で失敗していた場合はbundle lock --add-platform x86_64-linuxなどのヒントが書かれているはずです。そうした経験の積み重ねが、あなたを熟練に導いてくれます。(コラム 1.2

1.5.3 Herokuにデプロイする(2)

失礼、その2はありません。以上でおしまいです。

デプロイされたアプリケーションの表示は、heroku createリスト 1.23)を実行した際に生成されたアドレスをブラウザで開くだけです37。実行結果を図 1.35に示します。ページの内容は図 1.22とまったく同じですが、今やそれがインターネット上の本番Webページとして確かに公開されているのです38

6
図 1.35: Heroku上で動いている最初のRailsチュートリアルアプリケーション

演習

  1. 1.3.4.1と同じ変更を行い、本番アプリでも「hola, mundo!」を表示できるようにしてください。
  2. 1.3.4.1と同様、ルートへのルーティングを変更してgoodbyeアクションの結果が表示されるようにしてください。またデプロイ時には、Git pushのmasterをあえて省略し、git push herokuでデプロイできることを確認してみてください。

1.5.4 Herokuコマンド

Herokuのコマンドはたくさんあるので、ここでは簡単に触れる程度にとどめますが、少しだけ使ってみましょう。アプリケーションの名前を変更してみます。

$ heroku rename rails-tutorial-hello

rails-tutorial-helloは本書で既に使っているため、上記のコマンドを実行するとエラーになります。

実際は、Herokuで生成されたデフォルトのアドレスでも十分です。本当にアプリケーションの名前を変えてみたい場合は、次のようなランダムなサブドメイン名を設定し、この章の冒頭で説明したアプリケーションのセキュリティを実装してみる方法もあります。

hwpcbmze.herokuapp.com
seyjhflo.herokuapp.com
jhyicevg.herokuapp.com

このようなでたらめのサブドメイン名なら、URLを教えない限りサイトにアクセスされる心配もありません39。ちなみに、Rubyの威力の一端をお見せするために、サブドメイン用のランダムな文字列を生成するコンパクトなコードをササっと書いてみます。

('a'..'z').to_a.shuffle[0..7].join

ここで使ったコード片は4でまた登場します。40

Herokuではサブドメインの他に独自ドメインも使えます。実を言うと、このRailsチュートリアルもHeroku上に置かれているのです。したがって、本チュートリアルをオンラインで読んでいるのであれば、まさに今HerokuにホスティングされたWebサイトを見ているということになります。カスタムドメインや他のHeroku関連の詳細な情報については、Herokuのドキュメントを参照してください。

演習

  1. heroku helpコマンドを実行し、Herokuコマンドの一覧を表示してみてください。Herokuアプリのログを表示するコマンドはどれですか?
  2. 上の演習で見つけたコマンドを使って、Herokuアプリの最近のログ(log)を調べてみましょう。直近に発生したイベントは何でしたか?(このログを調べるコマンドを覚えておくと、本番環境の不具合を見つけるときに役立ちます)

1.6 最後に

この章では開発環境のセットアップやインストール、バージョン管理、本番環境へのデプロイなど、多くの課題を乗り越えました。次の章では1で学んだことを基礎として、データベースも備えたtoyアプリを作りながらRailsでできることの概観を学びます。

また、各章の最後にはTwitterで進捗を投稿できるボタンがあります。ハッシュタグ『#Railsチュートリアル』を使って他の学習者と繋がることもできるので、ぜひお気軽にご活用ください。

Railsチュートリアルには公式Twitterアカウント『@RailsTutorialJP41もあります。Railsチュートリアルの最新情報を周知したり学習者のコメントをハイライトしているので、よければこちらもフォローしてみてください。

1.6.1 本章のまとめ

  • Ruby on Railsとは、Webアプリケーションを開発するためのフレームワークであり、プログラミング言語Rubyで作られている。
  • クラウドIDEを利用すると、Railsのインストールやアプリケーションの生成、生成したファイルの編集などが簡単にができる。
  • Railsにはrailsコマンドが用意されていて、rails newで新しいアプリケーションを生成したり、rails serverで開発環境用のサーバーを立ち上げられる。
  • コントローラのアクションを追加したり、ルーティングを変更するだけで「hello, world」を表示するアプリケーションが作れた。
  • データの喪失を防止し、他の開発者と共同作業できるようにするため、Gitによるバージョン管理を導入し、GitHubの非公開リポジトリに作った。
  • Gitを導入していたため、git push herokuコマンドで作成したアプリケーションを本番環境(Heroku)にすぐデプロイできた。

1.7 本チュートリアルで用いている慣習

これまで紹介されたコマンドやコード(「リスト」と書かれている部分)を読んで、「読み方が分からなかった」と感じた方は本セクションを読んでみてください。特に問題なかった場合は、本セクションを読み飛ばし、次の章に進んでも大丈夫です。

本セクションでは、本チュートリアルで実行するコマンドや変更するコードの「読み方」を説明しています。なるべく読んですぐ分かるよう工夫していますが、読み方が分からなかった場合は本セクションをご活用ください。

本チュートリアルでWebアプリケーション開発を進めるときは、大きく分けて「コマンドを実行するとき」と「コードを変更するとき」の2つがあります。コマンドライン上でコマンドを実行して欲しいときは、以下のように先頭にドル記号($)を付けて表記します。

$ echo "hello, world"
hello, world

たとえば本章の1.3.2では、rails serverコマンドを実行してWebサーバーを起動するときは次のように表記しました。

$ rails server

コマンドラインでは、特定のディレクトリ内にあるファイルを指定することもあります。ディレクトリはスラッシュ記号(/)を使って表記するため、たとえばRailsアプリケーションの本番環境用設定ファイル(production.rb)の中身をコマンドライン上で表示する場合は、以下のように表記します。

$ cat config/environments/production.rb

上の例では、Railsアプリケーションのルートディレクトリ(README.mdファイルがあるディレクトリ)でコマンドを実行している点に注意してください。このルートディレクトリの位置はシステムによって異なります。たとえばCloud9(1.2.1)を使っている場合は、以下の場所がルートディレクトリになります。

/home/ubuntu/environment/hello_app/

つまり、上で示したproduction.rbファイルの場所を省略せずに表記する(絶対パスで表記する)場合は、以下のようになります。

/home/ubuntu/environment/hello_app/config/environments/production.rb

本チュートリアルでは、1つ1つのファイルを絶対パスで書くことはせず、基本的にconfig/environments/production.rbのように省略した形で表記します。

(ここまで読んで「よく分からない!」と感じても大丈夫です。そういった方々を対象とした コマンドライン編もあります。必要になったらぜひご活用ください。)

Railsチュートリアルで「コードを変更するとき」は、サンプルコードをより読みやすくするため、次の2つの工夫をしています。1つ目は、注目して欲しい行のハイライトです。

class User < ApplicationRecord
  validates :name,  presence: true
  validates :email, presence: true
end

上のようにコード行をハイライトして、そのコードサンプルで追加された新しい行を示したり、その前のコードサンプルとの違うを示すことがあります。2つ目は、同じコードを何度も書かずに省略するために、以下のようにドット(.)を縦に並べる表記です。

class User < ApplicationRecord
  .
  .
  .
  has_secure_password
end

この縦のドットはコードが省略されていることを表しているので、そのままコピペしないようご注意ください。

RailsチュートリアルではRailsアプリケーションをテストする方法についても解説していますので、ほんの小さな違いが原因でテストが失敗することもあれば(テストが失敗すると赤い文字で表示されます)、テストが成功パスすることもある(テストスイートがパスすると緑色の文字で表示されます)ことを知っておくと何かと役に立ちます。わかりやすくするため、失敗するテストには red 、パスするテストには green と書いてあります。

最後に、Railsチュートリアルでは今後さまざまなコマンドやコードを紹介し、可能な範囲でその出力結果も載せていきます。掲載されている出力結果と皆さんの出力結果が完全に一致しなくても、慌てないでください。こうした微細な違いが問題になることはほとんどありません。

一方で、上で紹介したファイルパスの読み間違えて違うファイルを修正したり、Cloud9以外の環境で開発したり、ファイル内にタイポが混入したり、コミットをし忘れたりと、さまざまな要因で皆さんは今後エラーに遭遇します。実際の現場の開発がそうであるように、一度もエラーに遭遇せずに本チュートリアルを完走することは滅多にないと思ってください。

そうしたエラーを本チュートリアルで1つ残らず網羅しようとするのは現実的ではないため、本チュートリアルを進めていてエラーが出たときは「エラーメッセージで検索する」という手法をオススメしています。これは現実のソフトウェア開発においても非常に有用な手法です(コラム 1.2)。また、本チュートリアルのヘルプページでは(網羅はしていませんが)よくあるエラーの解決手段も紹介しています。こちらも皆さんが本チュートリアルを進めていくときのご参考になれば嬉しいです。

エラーメッセージは、開発者のデバッグを助ける心強い味方です。エラーが出たときは本セクションを思い出し、ぜひ落ち着いて対応してください。より多くの方が本チュートリアルを完走できるよう願っています。

1. 他にも旅行水産物流貿易無人管理工事建設医療法務教育保育学習VRなどの業界で採用され、2023年12月には宇宙ビジネスでも上場しました。各業界の活用事例はRuby AssociationのWebサイトから確認できます。
2. Railsの設計哲学の詳細は「The Rails Doctrine(日本語訳)」からお読みいただけます。
3. Hotwireについては本チュートリアル完走者を対象とした「読み物ガイド」や、Rails 7の推しポイントを解説したYouTube動画などでも紹介されています。
4. なお、ローカル環境で挑戦したい方向けに「Visual Studio CodeとDockerコンテナを使って開発する」セクションをヘルプページに設けています。Dockerを用いた開発環境に興味がある方はお試しください。ご提供いただいたsaboyutakaに感謝します。
5. 例えば世界中から技術者・研究者が集まるGoogle Brainチームでも、15分ルール(何かに詰まった時、まず自分で15分解決を試みなさい。そして、15分経ったら、他の人に助けを求めなさい。)が採用されています。
6. 例えばfooという名前のメソッド定義を見つけるには、「def foo」をグローバル検索します。
7. AWSのサイトは継続的に更新されているため、詳細な手順は異なっているかもしれません。コラム 1.2の「熟練」の考え方を参考に細かな差異にも対応してみましょう。
8. 本チュートリアルをやった経験のある方なら、“rails-tutorial-6”のようにちょっと名前を変えて新しい環境で始めるとよいでしょう。
9. rbenvというツールでも同じことができます。日本ではrbenvの方が普及しているようです。
10. ここではコマンドライン編2.23.1で解説したechoコマンドと>>(append)コマンドを使います。>>は賢いので、append先にファイルが存在しない場合は新たに作ってくれます。
11. この手順は、ネイティブシステムとクラウドIDEのディレクトリ構成を一致させるためのものです。「熟練」している方はこの手順をスキップしてお好きなディレクトリ構成で進めていただいて構いません。
12. 「シェル」とは、実際に動くコマンドやプログラムに「殻(shell)のようにかぶさっている」インターフェイスと考えるとよいでしょう。
13. 操作を誤ったときの被害もその分甚大ですが。
14. これは「熟練」の典型的な例と言ってよいでしょう(コラム 1.2)。
15. 同様にして、~> 6.0と指定するとバージョン6.9のgemがインストールされる可能性はありますが、6.0がインストールされることはありません。この指定法は、gemのプロジェクトがセマンティックバージョニング(略称: semver)と呼ばれる方式でバージョン番号を管理している場合、特に便利です。セマンティックバージョニングとは、ソフトウェア同士の依存関係を壊さないよう変更を最小限にしてリリース番号を与える方法です。
16. コマンドラインでgem list <gem名>を実行して各gemの正確なバージョン番号を知ることもできますが、リスト  1.8を使うのが無難でしょう。
17. 表 3.1に示したように、実はinstallを省略できます。bundleコマンドそれ自体がbundle installのエイリアスであるためです。
18. ここで“C”はキーボードの文字を指していますが、大文字という意味ではありませんので、わざわざShiftキーを押して大文字の“C”にする必要はありません。
19. 本チュートリアルで使っている図中のCloud9のURLは、rails-tutorial-c9-mhartl.c9.io からAWS上の特定のURLに変更されています。スクリーンショットを撮った時点と現時点との合間にURLの規則が変わる可能性がありますが、都合上、元のままにしています(図 1.22)。この程度の小さな不一致であれば自力で解決できるぐらいのスキルを、一緒に本チュートリアルで身につけていきましょう(コラム 1.2)。
20. 利用しているエディタによっては「invalid multibyte character」といったエラーメッセージが表示されることがあるかもしれませんが、気にする必要はありません。このメッセージを表示しないようにする方法が知りたい場合は、エラーメッセージでググってみてください。
21. ちなみに筆者は、こういうときVimというエディタをデフォルトに設定するのが好みです。テキストエディタ編「最小限の環境で使えるVimエディタ」にも書いたように、最小限の設定で使いたい方にオススメです。vimを使いたい方は、リスト 1.15`which nano`の部分を`which vim`に書き換えて使ってください。
22. 理論上はもっと長い時間パスワードを保持することもできますが、Cloud9ではどうやらこのタイマーが1日1回リセットされるようなので、これ以上長い時間を設定してもあまり意味はなさそうです。
23. 多くの開発者はgit add .git add ファイル名といった対象ファイルを明示的に指定するコマンドを使います。本書では読者の躓きを減らす目的で-Aを使いますが、もしそれぞれの違いが気になったらGitの公式ドキュメントで各コマンドの違いを調べてみましょう。
24. チュートリアル本編ではこのファイルを修正することはありませんが、3.6.gitignoreファイルへの追加例があります。これは、3.6で行うオプションの詳細テスト設定の一部です。
25. HerokuやAWS、SendGridなどの有料プランが無料で使える「GitHub Education 学生開発者パック」という学生向け支援プログラムもあります。学校が発行するメールアドレスまたは学生証などの証明書類で登録・申請できるので、GitHubアカウント作成後、ぜひ検討してみてください。
26. 現在のGitHubは、Public/Private問わず、無料でリポジトリを作成できます。
27. もう一方のSSHオプション(図 1.28)は中級ユーザー向けです。SSH鍵の生成や登録が必要になり、ここで躓く方が多かったため本チュートリアルではHTTPSオプションの選択をオススメしています。もしSSHオプションで進める場合は、前述したリスト 1.17のパスワードを一定時間保持する設定や、後述する個人アクセストークンの作成が不要になります。
28. 個人アクセストークンは期限が切れた場合など、必要に応じていつでも作成できます。トークンに含める設定を後から変更することも可能です。
29. -uオプションについては今はまだ気にしなくても大丈夫です。気になる方は "git set upstream" で検索してみてください。
30. Markdownの詳細は テキストエディタ編Git/GitHub編をご覧ください。
31. Gitに対応したアプリケーションもあります。例えばGitリポジトリの内容を視覚的に表示したい場合は、AtlassianのSourceTreeなどが便利です。
32. 共同開発について詳しく知りたい方は Git/GitHub編第4章「Gitで共同作業する」をご覧ください。
33. 日本語であれば「〜を追加」などの体言止めがよいでしょう。
34. 作りかけの恥ずかしいWebアプリケーションをネットにうっかり公開してしまわないだろうかと心配する方もいらっしゃるかと思いますが、Railsチュートリアルではそれを防ぐための方法も紹介するのでご安心ください。1.5.4はその方法の1つです。
35. SQLiteはスマートフォンなどの組み込みデータベースとして広く用いられています。また、セットアップがとても簡単なのでRailsでも開発環境(development)におけるデフォルトのデータベースとして使われています。とはいえ本番環境で使うデータベースでは、きわめて多くの更新を同時にかけることがあり、SQliteはそうした同時更新が得意ではないため、開発環境と本番環境で別々のデータベースを使うようにしています。詳細は3.1をご参照ください。
36. なぜ失敗することがあるかというと、pg gemをインストールするためにはPostgreSQLデータベースを開発環境にセットアップする必要があるからです。もちろん開発環境にPostgreSQLデータベースをセットアップしても解決できるのですが、手順がやや複雑になるため、今回はスキップする方法を選択しています。
37. もちろんここに表示されている著者のアドレスではなく、あなたのアドレスを使ってください。クラウドIDEではなくローカルコンピュータで作業している場合は heroku open コマンドで自動的にブラウザ表示することもできます。
38. 1.3.4.1の演習を完了した方は表示結果が少し違うかもしれません。
39. このソリューションは通称「曖昧さを利用したセキュリティ」と呼ばれ、本チュートリアルや趣味目的のアプリケーションであれば十分有効です。もしどうしても気になる場合はRailsのBASIC認証の利用をオススメします。とはいえBASIC認証も初心者にはやや高度で、それなりに熟達したスキルが必要となります(コラム 1.2)。
40. Rubyではよくあることですが、実はもっとコンパクトに書けます。今回の例では、Rubyのsampleメソッドを使うことで ('a'..'z').to_a.sample(8).join と書くこともできます。指摘してくれた読者のStefan Pochmannに感謝! 著者もまた新たなRubyの一面に触れられました。
41. 最新のRailsチュートリアル情報が分かるRailsチュートリアルマガジンもオススメです。フォローすると最新記事をメールでお知らせします。
前の章
第1章 ゼロからデプロイまで Rails 6 (第6版)
次の章