Ruby on Rails チュートリアル

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

古い過去アーカイブ版を表示しています。史料として残してありますが、既に更新が止まっておりセキュリティ上の問題もあるため、学習で使うときは最新版をご利用ください。

第4版 目次

推薦の言葉

私が前にいた会社(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 on Rails(略称『Rails』)は、プログラミング言語『Ruby』で書かれたフリーかつオープンソースのWeb開発フレームワークです。

Railsは本格的なWebサービスを開発するツールとして急速に有名になり、海外ではGitHubShopifyDisneyHuluAirbnbSoundCloudイギリス政府などで採用され、ドイツの政府系ファンド(STF)もRuby/Railsを支援しています。また日本国内でもCookpadnotefreeeマネーフォワードYAMAPCrowdWorksQiitaZennpixivGame8STORES駅すぱあと、自治体に導入されているつながる相談などで採用されています。Rubyを採用している上場企業は45社以上にのぼり、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サービス開発にふさわしい魅力的なフレームワークなのです。

コラム 1.1. お手軽すぎるScaffoldの甘い誘惑

Railsの作者David Heinemer Hansson氏による有名な動画「15分で作るブログ (英語)」が強い印象を与えたおかげで、Railsは立ち上げ当初から一気に盛り上がりました。この後にも続々同じような動画が作られていますが、いずれもRailsの能力の一端を垣間見るにはうってつけなので、ぜひ一度ご覧ください。ただし、動画では「15分でブログを作る」ためにScaffoldというお手軽生成機能を使っています。Railsの魔法のようなgenerate scaffoldコマンドで自動生成したコードがあるからこそ、このような早業が可能なのです。

実際、筆者はRuby on Rails のチュートリアルを書きながら、あまりにもお手軽にコードを生成できる (訳注: 原文の「quicker, easier, more seductive」は、スターウォーズ・エピソードVのヨーダの台詞の引用) scaffoldの機能を使う誘惑にかられることが何度もありました。しかし、自動生成されたコードは無駄に量が多く複雑で、Rails初心者には向いていません。たとえ運よく動いたとしても、正常に動いている理由を解明するのはおそらく無理です。scaffoldの自動生成コードに頼っている限り、コード自動生成の達人にはなれるかもしれませんが、Railsに関する実践的な知識はほとんど身に付きません。

Railsチュートリアルでは、より実践的な知識を身につけるために、Scaffoldとほぼ逆のアプローチで開発を進めていきます。具体的には、2で作成する簡単なデモアプリではscaffoldを使いますが、このチュートリアルの中核である3以降のサンプルアプリケーションからは、scaffoldを一切使わずに開発を進めていきます。scaffold を使わない代わりに、開発の各ステップで、手頃な一口サイズのコードを書いてもらいます。この一口サイズのコードは、無理なく理解できる程度にシンプルで、かつ、ある程度の歯ごたえとやりがいを得られるように配慮してあります。各ステップで理解する必要のあるコードの量はわずかですが、こうした理解を積み重ねていくことで、最終的にRailsの知識を高いレベルで身につけられるように構成されています。このようにして得た深い知識は柔軟性が高く、どのようなWebアプリを作成する時にも応用が効きます。

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

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

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

1.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を選んだのは間違いではなかった」と強調しています)

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

images/figures/hello_world_hello_app
図 1.2: 最初に作るhelloアプリ
images/figures/micropost_length_error
図 1.3: 次に作るtoyアプリ
images/figures/home_page_with_feed
図 1.4: 最後につくるサンプルアプリ

1.1.2 この本における取り決め

本チュートリアルで使う記法のほとんどは説明不要だと思いますが、説明が必要だと思われるものについてのみ、このセクションで補足します。

本チュートリアルでは、コマンドライン (ターミナル) のコマンド例が多用されています。簡素化のため、次のようなUnixスタイルのプロンプト (行の頭に「$」を表示するスタイル) を使って、その例がコマンドラインであることを示しています。

$ echo "hello world"
hello world"

Railsにはコマンドラインから実行するコマンドが多数あります。例えば1.3.2では、rails serverコマンドを使ってローカル環境にWebサーバーを立ち上げたりします。

$ rails server

Railsチュートリアルにおけるディレクトリの区切りは、コマンドラインのプロンプトと同様にUnixスタイルのスラッシュ「/」を使っています。例えば、sample_appのproduction.rbの設定ファイルは次のように表します。

config/environments/production.rb

このようなファイルパスは、アプリケーションのルートディレクトリからの相対パスであると理解してください。ルートディレクトリの位置はシステムによって異なり、このクラウドIDE (1.2.1) の場合は以下のようになります。

/home/ec2-user/environment/sample_app/

この場合、production.rbへの絶対パスは以下のようになります。

/home/ec2-user/environment/sample_app/config/environments/production.rb

表記を簡単にするため、本チュートリアルでは原則としてconfig/environments/production.rbと記述し、ルートディレクトリより上のパスは省略します。

Railsチュートリアルや実践入門シリーズでは、なるべくプログラムの出力結果も記載するようにしています。出力結果は、お使いのOSやそのバージョンなどによって異なるので、本チュートリアルの出力結果と皆さんの出力結果が完全に一致するとは限りません。

また、同じ理由で、皆さんがコマンドを実行したときにエラーが発生することもあります。そのような場合は、エラーメッセージをGoogleで検索してください。エラーメッセージをGoogleで検索することは、実際のソフトウェア開発でも使われている基本的なテクニックなので、技術力向上という視点で見ても良い練習になります (コラム 1.2)。よくある事例についてはヘルプページでまとめています。困ったときに思い出していただけると嬉しいです。

本書ではWebアプリケーションのテストも扱っています。どうなるとテストが失敗し、どうするとテストが成功するか、手を動かしながら学べるようになっています。読みやすさのため、テストが失敗するコードを red 、テストが成功するコードを green で表記します。

最後に、サンプルコードの更新箇所を分かりやすくするために、次の2つの工夫を加えました。1つは、コードの重要な部分にハイライトを追加したことです。

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

ハイライト行は通常、コードに追加された行を示しますが、その前に示したコードとの違いを強調していることもよくあります (常にというわけではありませんが)。もう1つは、長いコードの途中を次のように連続ドットで省略したことです。

class User < ApplicationRecord
  .
  .
  .
  has_secure_password
end

連続ドットは省略を表しているので、他のコードと一緒にコピーしないようご注意ください。

演習

Railsチュートリアルでは多くの演習を用意しています。随所に配置した演習は、飛ばさずに最後まで解くことを強くオススメします。

本編と演習問題を分けるため、原則として演習問題の解答はその後の本編コードリストで使わないようにしています。逆の言い方をすれば、演習問題によって生じた違いが原因で、先に進んだときにコードにささいな違いが生じる可能性があるということです。しかしながら、こうした違いを挑戦と捉えて自力で解決することも、皆さんの技術力の向上に大いに役立ちます。ぜひ、最後まで飛ばさずに解いてみてください (コラム 1.2)。

演習で用意した課題には難しいものもありますが、まずは簡単な演習で腕試しをしてみましょう。

  1. Ruby on Railsで使うRuby gemはどのWebサイトにありますか?ヒント: 分からないときはとにかくググりましょう
  2. 現時点でのRailsの最新バージョンはいくつですか?
  3. Ruby on Railsはこれまでに何回ダウンロードされたでしょうか?調べてみてください。

1.2 さっそく動かす

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

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

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

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

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

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

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

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

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

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

1.2.1 開発環境

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

ちなみにローカル環境で開発を進めることもできますが、Railsの開発環境のセットアップはやや難しいため、ほとんどの読者にとってはクラウドIDEが最適だと筆者は考えています。もしローカル環境でセットアップしたい場合は Learn Enough Dev Environment to Be Dangerousの手順に従ってください (訳注: 日本語だとRails Girls インストール・レシピが詳しいです。仮想環境 (Vagrant) を使った環境構築もあります)。

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

images/figures/ide_anatomy_aws
図 1.6: クラウドIDEの外観

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

  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のような画面になるまで進めてください。情報を適宜入力して確認ボタンを押し、次のページでは、Amazon LinuxではなくUbuntu Serverを選択して進めます。すると、Cloud9の開発環境が利用できるようになります。 (図 1.9)。このとき “root” ユーザーであるという警告メッセージが表示されるときがありますが、こちらの対処方法は後ほど説明します (IAMという機能を使った対応方法について13.4.4で説明します)。
images/figures/cloud9_page_aws
図 1.7: Cloud9の管理ページ
images/figures/cloud9_name_environment
図 1.8: AWS Cloud9で新しいワークスペースを作成する
images/figures/cloud9_ide_aws
図 1.9: クラウドIDEの初期画面

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

images/figures/cloud9_two_spaces_aws
図 1.10: Cloud9でインデントをスペース2つに設定する

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

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

1.2.2 Railsをインストールする

1.2.1の開発環境には必要なソフトウェアがすべて含まれていますが、Railsそのものは含まれていません。そこでよくある便利な設定とインストールを済ませてしまいましょう。最初に、Rubyドキュメントのインストールで無駄な時間を使わないよう、コマンドに設定を少々追加してみましょう (訳注: Rubyドキュメントのインストールに数分ほどかかることがあるので、エンジニアの間ではよくある設定の1つです)。これはシステムで1回だけ設定しておけばOKです。このコマンドの意味がわからなくても、今は何の問題もありませんのでご心配なく7

$ printf "install: --no-document \nupdate:  --no-document\n" >> ~/.gemrc

次に、Railsをインストールするためにgemコマンドを使います。このコマンドはRubyGemsパッケージマネージャーが提供しており、コマンドライン (ターミナル) にリスト 1.1のように入力するときに使います。ローカルシステム上で開発する場合はターミナルを使います。クラウドIDEを使っている場合は、図 1.6のコマンドラインエリアに入力してください。

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

-vというオプションを使うことで、インストールされるRailsのバージョンを指定できます。つまり、この後のチュートリアルはRails 5.1で進めていくことになります。なお、Rails 5.1は現在サポート対象外となっています。詳細は以下の注意事項をお読みください。

Rails 5.1は現在サポート対象外となっています。バグ修正やセキュリティ問題などは今後更新される予定はなく、Herokuへのデプロイなども出来ない可能性が高いです。最新版は継続的に更新されていて、ここまでの内容も同じであるため、最新版に切り替えて続きを読むことを強くオススメします。

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

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

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

リスト 1.2: Railsプロジェクトで使うenvironmentディレクトリを作成する(クラウドの場合は不要)
$ cd                  # ホームディレクトリに移動する
$ mkdir environment     # 'environment' ディレクトリを作成する
$ cd environment/       # 'environment' ディレクトリに移動する
コラム 1.3. 急いで学びたい人のためのUnixコマンドライン講座

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

コマンドラインの基本的な仕組みは本当にシンプルです。ユーザーはコマンドを発行 (issue) することで、実にさまざまな操作を実行できます。ディレクトリの作成ならmkdirコマンド、ファイルの移動やリネームはmvコマンド、ファイルのコピーならcpコマンド、ファイルシステム内でのディレクトリの移動はcdコマンド、という具合です。GUI (グラフィカルユーザーインターフェイス) しか使ったことのないユーザーからすると、コマンドラインの黒い画面は何やら恐ろしげでとっつきが悪いように見えるかもしれませんが、見た目ほど当てにならないものはありません。コマンドラインはそれ自体が強力なツールであり、エンジニアにとってなくてはならない道具箱なのです (訳注: 操作を誤ったときの被害もその分甚大ですが)。そうでなければ、どうしてエンジニアが揃いも揃ってコマンドラインを使うでしょうか。経験豊富な開発者のデスクトップ画面を覗きこめば、十中八九どころか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.3のコマンドを使った最初のアプリケーションの作成です。リスト 1.3のコマンドでは、Railsのバージョンを明示的に指定している点にご注目ください。このようにバージョンを指定することで、リスト 1.1と同じバージョンのRailsで、最初のアプリケーションと同じファイル構造を作成することができます。(リスト  1.3を実行すると「Could not find 'railties'」というエラーが表示される場合は、インストールしたRailsのバージョンが正しくない可能性があります。リスト 1.1のとおりにコマンドを実行したかどうかを念のためもう一度確認してください。)

リスト 1.3: rails newを実行する (バージョン番号を指定)
$ cd ~/environment
$ rails _5.1.6_ new hello_app
      create
      create  README.md
      create  Rakefile
      create  config.ru
      create  .gitignore
      create  Gemfile
      create  app
      create  app/assets/config/manifest.js
      create  app/assets/javascripts/application.js
      create  app/assets/javascripts/cable.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  tmp/cache/assets
      create  vendor/assets/javascripts
      create  vendor/assets/javascripts/.keep
      create  vendor/assets/stylesheets
      create  vendor/assets/stylesheets/.keep
      remove  config/initializers/cors.rb
         run  bundle install
Fetching gem metadata from https://rubygems.org/..........
Fetching additional metadata from https://rubygems.org/..
Resolving dependencies...
Installing rake 11.1.2
Using concurrent-ruby 1.0.2
.
.
.
Your bundle is complete!
Use `bundle show [gemname]` to see where a bundled gem is installed.
         run  bundle exec spring binstub --all
* bin/rake: spring inserted
* bin/rails: spring inserted

リスト 1.3の下の方にご注目ください。rails newを実行すると、ファイルの作成後にbundle installコマンドが自動的に実行されています。このbundle installコマンドの意味については1.3.1の最初で詳しくご説明します。

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

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

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

1.3.1 Bundler

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

images/figures/cloud9_gemfile_aws
図 1.12: デフォルトのGemfileをテキストエディタで開く
リスト 1.4: hello_appディレクトリにあるデフォルトのGemfile Gemfile
source 'https://rubygems.org'

git_source(:github) do |repo_name|
  repo_name = "#{repo_name}/#{repo_name}" unless repo_name.include?("/")
  "https://github.com/#{repo_name}.git"
end

# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '~> 5.1.6'
# Use sqlite3 as the database for Active Record
gem 'sqlite3'
# Use Puma as the app server
gem 'puma', '~> 3.7'
# Use SCSS for stylesheets
gem 'sass-rails', '~> 5.0'
# Use Uglifier as compressor for JavaScript assets
gem 'uglifier', '>= 1.3.0'
# Use CoffeeScript for .coffee assets and views
gem 'coffee-rails', '~> 4.2'
# See https://github.com/rails/execjs#readme
# for more supported runtimes
# gem 'therubyracer', platforms: :ruby

# Use CoffeeScript for .coffee assets and views
gem 'coffee-rails', '~> 4.2'
# Turbolinks makes navigating your web application faster.
# Read more: https://github.com/turbolinks/turbolinks
gem 'turbolinks', '~> 5.x'
# Build JSON APIs with ease.
# Read more: https://github.com/rails/jbuilder
gem 'jbuilder', '~> 2.0'
# Use Redis adapter to run Action Cable in production
# gem 'redis', '~> 3.0'
# Use ActiveModel has_secure_password
# gem 'bcrypt', '~> 3.1.7'

# Use Capistrano for deployment
# gem 'capistrano-rails', group: :development

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]
  # Adds support for Capybara system testing and selenium driver
  gem 'capybara', '~> 2.13'
  gem 'selenium-webdriver'
end

group :development do
  # Access an IRB console on exception pages or by using
  # <%= console %> anywhere in the code.
  gem 'web-console'
  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

# Windows環境ではtzinfo-dataというgemを含める必要があります
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]

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

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

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

gem 'sqlite3'

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

gem 'uglifier', '>= 1.3.0'

uglifierのバージョンが1.3.0以上であれば最新バージョンのgemがインストールされます。極端に言えば、バージョンが7.2であってもそれが最新ならインストールされます (なお、uglifierはAsset Pipelineでファイル圧縮を行うためのものです)。2番目の方法は次のとおりです。

gem 'coffee-rails', '~> 4.0.0'

このように指定すると、coffee-rails (これもAsset Pipelineで使うgemです) のバージョンが4.0.0より大きく、4.1より小さい場合にインストールされます。つまり、以下のコードを実行すると、>=という記法では常に最新のgemがインストールされ、~> 4.0.0という記法ではマイナーバージョンの部分に相当するアップデート済みのgem (例: 4.0.0から4.0.1) をインストールします。後者の場合、メジャーバージョン (例: 4.0から4.1) のリリースはインストールされません9。残念ながら、経験上ちょっとしたマイナーアップグレードですら問題を引き起こすことがあります。このため、Railsチュートリアルでは基本的に事実上すべてのgemでバージョンを「ピンポイントで」指定し、がっちり固定してあります。ベテラン開発者であれば、Gemfile~> を使って指定し、最新のgemを使って進めてもらっても構いません。ただし、バージョンが異なると本チュートリアルに記載されている挙動と異なる可能性がありますので、その場合は各自でご対応願います。

リスト 1.4Gemfileを、実際に使用する正確なバージョンのgemに置き換えたものをリスト 1.5に示します。(コマンドラインでgem list <gem名>を実行して各gemの正確なバージョン番号を知ることもできますが、リスト  1.5を使うのが無難でしょう)。なお、この置換えのついでに、sqlite3 gemをdevelopment環境とtest環境 (7.1.1) だけで使う (つまりproduction環境では使わない) ように変更している点にもご注目ください。これは、後でHerokuで使うデータベースと競合する可能性を防ぐための処置です (1.5)。

本書のGemfileで固定した各gemのバージョンは公式リポジトリと一致している必要があります。現在の章に合わせてご参照ください。Webテキスト版は常に最新の状態となるため問題ありません。電子書籍版を読んでいる場合はご注意ください。
リスト 1.5: 各種Ruby gemの内容を一新させ、Rubyのバージョン番号を削除したGemfile Gemfile
source 'https://rubygems.org'

gem 'rails',        '5.1.6'
gem 'puma',         '3.9.1'
gem 'sass-rails',   '5.0.6'
gem 'uglifier',     '3.2.0'
gem 'coffee-rails', '4.2.2'
gem 'jquery-rails', '4.3.1'
gem 'turbolinks',   '5.0.1'
gem 'jbuilder',     '2.6.4'

group :development, :test do
  gem 'sqlite3',      '1.3.13'
  gem 'byebug', '9.0.6', platform: :mri
end

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

# Windows環境ではtzinfo-dataというgemを含める必要があります
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]

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

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

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

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

1.3.2 rails server

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

リスト 1.6: Railsサーバーを実行する
$ cd ~/environment/hello_app/
$ rails server
=> Booting Puma
=> Rails application starting on http://localhost:3000
=> Run `rails server -h` for more startup options
=> Ctrl-C to shutdown server

JavaScriptランタイムがインストールされていないというエラーが表示された場合は、GitHubのexecjsページにあるインストール可能なランタイムの一覧からJavaScriptランタイムを入手してください。個人的にはNode.jsがオススメです。

rails serverコマンドの実行は別のターミナルタブで行うことをオススメします。こうしておけば最初のターミナルタブで他のコマンドを実行できるからです。図 1.13図 1.14。既に最初のタブでサーバーを開始している場合は、Ctrl+Cを押すとサーバーを終了できます11。Railsアプリケーションを表示するには、ローカルサーバーの場合はhttp://localhost:3000/をブラウザで開きます。クラウドIDEの場合は、[Share] を開いて、開きたいアプリケーションのアドレスをクリックします (図 1.15)。どちらの場合も、図 1.17のようにブラウザにRailsアプリケーションが表示されます。

images/figures/new_terminal_tab_aws
図 1.13: 新しいターミナルタブを開く
images/figures/rails_server_new_tab_aws
図 1.14: 別のタブでRailsサーバーを実行する
images/figures/share_workspace_aws
図 1.15: クラウドワークスペース上で実行しているローカルサーバーを共有する
images/figures/full_browser_window_aws
図 1.16: アプリケーションをブラウザで開いたときの画面
images/figures/riding_rails_4th_edition_aws
図 1.17: rails serverを実行したときのデフォルトのRailsページ

演習

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

1.3.3 Model-View-Controller (MVC)

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

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

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

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

1.3.4 Hello, world!

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

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

$ ls app/controllers/*_controller.rb

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

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

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

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

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

root 'controller_name#action_name'

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

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

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

images/figures/hello_world_hello_app
図 1.19: 「hello, world!」をブラウザで表示する

演習

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

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

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

バージョン管理システムにもさまざまなものがありますが、RailsコミュニティではLinuxカーネル用にLinus Torvaldsにより開発された分散バージョン管理システムであるGitが主流になっています。Git はそれだけで大きなテーマなので、すべてを説明しようとすると軽く一冊の本を超えてしまいます。詳しくは Git/GitHub編をご覧ください14

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

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

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

git configで設定

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

$ git config --global user.name "Your Name"
$ git config --global user.email your.email@example.com

このgit configで設定する名前やメールアドレスは、今後リポジトリ上で一般に公開されますのでご注意ください

git initでセットアップ

今度は、リポジトリごとに作成の必要な作業を行います。まず、Railsアプリケーションのルートディレクトリに移動し、新しいリポジトリの初期化を行います。

$ git init
  Initialized empty Git repository in
  /home/ec2-user/environment/environment/hello_app/.git/

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

$ git add -A

このコマンドを実行すると、現在のディレクトリにあるファイルがすべて追加されます。ただし、.gitignoreに記載されているパターンにファイル名がマッチする場合、そのファイルは追加されません。.gitignoreファイルは、rails newコマンドを実行すると自動的に生成され、Railsプロジェクト用のパターンも記入されます。もちろん、自分でパターンを追加しても構いません15

Gitにプロジェクトのファイルを追加すると、最初はステージング (Staging) という一種の待機用リポジトリに置かれ、コミットを待ちます。安全のため、いきなりコミットしないようになっているのです。ステージングの状態を知るにはstatusコマンドを使います。

$ git status
On branch master  Initial commit

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

  new file:   .gitignore
  new file:   Gemfile
  new file:   Gemfile.lock
  new file:   README.md
  new file:   Rakefile
  .
  .
  .

ステージングエリアで控えている変更を本格的にリポジトリに反映 (コミット) するには、commitコマンドを使います。

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

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

ここでコミットについて少し解説しておきます。Gitにおけるコミットは、あくまでローカルマシン上での操作であることに注意してください。git pushコマンドで変更をリモートリポジトリにプッシュする方法については1.4.4で解説します。

ちなみに、logコマンドでコミットメッセージの履歴を参照できます。

$ git log
commit: af72946fbebc15903b2770f92fae9081243dd1a1
Author: Michael Hartl <michael@michaelhartl.com>
Date:   Thu May 12 19:25:07 2016 +0000

    Initialize repository

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

1.4.2 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
Changed but not updated:
  (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

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 directory clean)
$ ls app/controllers/
application_controller.rb  concerns/

削除されたディレクトリとファイルを無事復旧できました。これでひと安心です。

1.4.3 Bitbucket

第4版はGitHubに対応していません。GitHubについて学びたい場合は最新版に切り替えてお読みください。

Gitを使ってプロジェクトをバージョン管理下に置くことができたので、今度はBitbucketにソースコードをアップロードしてみましょう。BitbucketはGitリポジトリのホスティングと共有に特化したサイトです (Git/GitHub編ではGitHubを使っていますが、コラム 1.4でBitbucketを使っている理由について説明しています)。リポジトリをBitbucketにわざわざプッシュするのには2つの理由があります。1つ目は、ソースコード (とそのすべての変更履歴) の完全なバックアップを作成することです。2つ目は、他の開発者との共同作業をより簡単に行うことです。

コラム 1.4. GitHubとBitbucket

GitHubとBitbucketは、Gitリポジトリを扱う2つの著名なサービスです。両者のサービスは非常に似通っています。どちらもGitリポジトリのホスティングと共同作業を行うことができ、リポジトリの表示や検索を行いやすくしてくれます。本チュートリアルとして採用する際の両者の重要な違いは、GitHubは「リポジトリを一般公開する場合は無料、公開しない場合は有料」なのに対し、Bitbucketは「共同作業者が一定数以下ならリポジトリを公開しなくても無料、共同作業者が一定数を超えると有料」である点です。なお、どちらも容量制限はありません。もちろん読者の皆さんの目的に応じて、どちらのサービスを選んでも構いません。

Git/GitHub編および本チュートリアルの以前の版では、オープンソースのサポートを強調するGitHubを採用していました。しかし本チュートリアルではWebアプリケーションの様々なコードを扱うため、全てのリポジトリがデフォルトで非公開になっている方がセキュリティ上安心して取り組めます。具体的には、本チュートリアルの後半で扱うコードには、暗号化キーやパスワードなどの機密情報が含まれます。このような情報を利用されると、サイトのセキュリティが脅かされるかもしれません。もちろん、.gitignoreなどの仕組みを利用すれば、そうした機密情報を適切に扱うことができます。しかしそのためにはそれなりの経験が必要であり、慣れた開発者でもたまに扱いを間違えてしまうことがありえるのです。本チュートリアルで作成するサンプルWebアプリケーションは公開してもまったく問題はありませんが、これらの理由により、一般公開されているリポジトリに置くことには若干のリスクが生じます。そういうわけで、リモートに置くリポジトリはデフォルトで非公開であることが望ましく、なるべく安全側に倒しておきたいと考えています。そしてGitHubでは、リポジトリを非公開にする場合は有料ですが、Bitbucketではリポジトリを非公開にしても容量無制限かつ無料で利用できます。このため、本チュートリアルの場合はGitHubよりもBitbucketの方が好都合であると言えます。

(ところで、近年ではGitLabというGitホスティング会社が第三勢力として急速に浮上していますね。元々は自分で設置するタイプのオープンソースのGitツールでしたが、現在はホスティングサービスも提供しており、公開型・非公開型のどちらのリポジトリも利用できます。今後のプロジェクトでは、GitHubやBitbucketに加えて、GitLabも有力な勢力となるでしょう。)

更新情報: 2019年1月からGitHubの非公開型レポジトリが無料になりました。共同作業できるメンバー数は限られているものの、非公開型のリポジトリが利用できるようになったため、Railsチュートリアル(第6版)ではGitHubを使用しています。

更新追記: HerokuやAWS、SendGridやTravis CIなどの有料プランが無料で使える「GitHub Education 学生開発者パック」という学生向け支援プログラムもあります。学校が発行するメールアドレスまたは学生証などの証明書類で登録・申請できるので、学生の方はぜひ検討してみてください。

Bitbucketでプロジェクトを開始するのは簡単ですが、少しだけ技術的に込み入った部分 (コラム 1.2) がありますので、次の要領で進めてください。

  1. Bitbucketアカウントがない場合はアカウントを作成します
  2. 公開鍵をクリップボードにコピーします。既に公開鍵を作成している場合は、リスト 1.10のようにcatコマンドを使って公開鍵を表示ができます。まだ作成していない場合はリスト 1.10のコマンドを実行しても No such file or directory と表示されます。まだ作成していない場合は「Git - SSH 公開鍵の作成」を参考に公開鍵・暗号鍵を作成してください。
  3. Bitbucketに公開鍵を追加するには、左下にあるアバター画像をクリックして [Bitbucket 設定]、[SSH 鍵] の順に選択します (図 1.22)。
リスト 1.10: catコマンドで公開鍵を出力する
$ cat ~/.ssh/id_rsa.pub
images/figures/add_public_key_ja
図 1.22: SSH公開鍵を追加する

公開鍵の追加が終わったら、左サイドバーの「+」マークから作成メニューを開き、[リポジトリ] をクリックして新しいリポジトリを作成します (図 1.23)。プロジェクト名を選択し16任意のリポジトリ名を入力したら、アクセスレベルの[非公開リポジトリ] のチェックボックスが「オン」になっていること、[READMEを含めますか?] と[Include .gitignore? ] が「No」になっていること、[Default branch name] が空白のまま17であることを確認してください。準備ができたら [リポジトリの作成] をクリックして、その後は画面の指示にしたがって進めてください。

images/figures/create_first_repository_bitbucket_4th_ed_ja
図 1.23: Bitbucketに最初のアプリのリポジトリを作成する

最終的に、リスト 1.11のようなコマンドが表示されたら成功です。もしリスト 1.11のような画面にならない場合は、公開鍵が正しく追加されていない可能性があるので、公開鍵の追加からやり直すことをオススメします。

最後は、画面に表示されたコマンドのとおりに入力して、ローカル環境にあるリポジトリをBitbucket上にプッシュできます。リポジトリをプッシュするときに「Are you sure you want to continue connecting (yes/no)?」と表示されることがありますが、そのときは「yes」と入力してください。

リスト 1.11: Bitbucketへのリポジトリ追加とリポジトリへのプッシュ
$ git remote add origin git@bitbucket.org:ユーザー名/hello_app.git
$ git push -u origin master

リスト 1.11の最初のコマンドは、BitbucketをリポジトリのoriginとしてGitの設定ファイルに追加するためのものです。次のコマンドでは、ローカルのリポジトリをリモートのoriginにプッシュします (-uフラグについては気にする必要はありません。気になるのであれば "git set upstream" で検索してみてください)。なお、「ユーザー名」の部分は実際のユーザー名に置き換える必要があります。例えば著者の場合、実行するコマンドは次のようになります。

$ git remote add origin git@bitbucket.org:railstutorial/hello_app.git

上のコマンドを実行すると、hello_appのリポジトリのページがBitbucketに作成されます。このページでは、ファイルの参照、全コミット履歴などさまざまな機能を利用できます (図 1.24)18

images/figures/bitbucket_repository_page_4th_ed
図 1.24: Bitbucketのリポジトリページ

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

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

Railsが自動生成したREADMEをそのまま使ってもよいですし、プロジェクトに合わせて内容を書き換えてももちろん構いません。ここでは、READMEをRailsチュートリアル固有の内容に合わせて書き換えてみましょう。それと同時に、Gitでbranch、edit、commit、mergeを行う際にお勧めのワークフローの実例をご覧いただきます20

images/figures/bitbucket_default_readme
図 1.25: Bitbucketで表示されるデフォルトのREADMEファイル

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ブランチに「*」が付いていることで、このブランチが現在使用中であることが示されています

ブランチの真価は他の開発者と共同で作業する時に発揮されますが21、本チュートリアルのように一人で作業する時にも非常に有用です。masterブランチはトピックブランチで行った変更に影響されないので、たとえブランチ上のコードがめちゃくちゃになってしまっても、masterブランチをチェックアウトしてトピックブランチを削除すれば、いつでも変更を破棄する事ができます。具体的な方法についてはこの章の最後で説明します。

ちなみに、通常このような小さな変更のためにわざわざブランチを作成する必要はありませんが、「よい習慣を形成するには早すぎる」ということはないので、今のうちに少しでも練習しておきましょう。

Edit (編集)

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

リスト 1.12: 新しい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](http://www.michaelhartl.com/). Hello, world!

Commit (コミット)

変更が終わったら、ブランチの状態を確認してみましょう。

$ 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 9dc4f64] Improve the README file
 1 file changed, 5 insertions(+), 22 deletions(-)

-aフラグは慎重に扱ってください。最後のコミット後に新しいファイルを追加した場合は、まずgit addを実行してバージョン管理下に置く必要があります。

コミットメッセージは現在形かつ命令形で書くようにしましょう (訳注: これは英語で書く場合のルールです。日本語であれば「〜を追加」などの体言止めがよいでしょう)。Gitのモデルは、(単一のパッチではなく) 一連のパッチとしてコミットされます。そのため、コミットメッセージを書くときには、そのコミットが「何をしたのか」と過去形の履歴スタイルで書くよりも「何をする」ためのものなのかを現在形かつ命令形で書く方が、後から見返したときにわかりやすくなります。さらに、現在形かつ命令形で書いておけば、Gitコマンド自身によって生成されるコミットメッセージとも時制が整合します。詳しくは Git/GitHub編「Gitにコミットするとは」 をご覧ください。

Merge (マージ)

ファイルの変更が終わったので、masterブランチにこの変更をマージ (merge) します。

$ git checkout master
Switched to branch 'master'
$ git merge modify-README
Updating af72946..9dc4f64
Fast-forward
 README.md | 27 +++++----------------------
 1 file changed, 5 insertions(+), 22 deletions(-)

Gitの出力には34f06b7のような文字列 (ハッシュ) が含まれていることがあります。Gitはこれらをリポジトリの内部処理に使っています。この文字列は環境の違いにより上記のものと少し異なるかもしれませんが、他の部分はほぼ同じはずです。

変更をマージした後は、git branch -dを実行してトピックブランチを削除すれば終わりです。

$ git branch -d modify-README
Deleted branch modify-README (was 9dc4f64).

トピックブランチの削除は必須ではありません。実際、トピックブランチを削除せずにそのままにしておくことはよく行われています。トピックブランチを削除せずに残しておけば、トピックブランチと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フラグは変更をマージしていなくてもブランチを削除してくれます。

Push (プッシュ)

READMEファイルの更新が終わったので、Bitbucketに変更をプッシュして結果を見てみましょう。既に1.4.3で一度プッシュを行ったので、大抵のシステムではgit pushを実行するときにorigin masterを省略できます。

$ git push

デフォルトのREADMEと同様、更新されたREADMEもBitbucketでよしなにHTMLに変換してくれます (図 1.26)。

images/figures/new_readme_bitbucket_4th_ed
図 1.26: Bitbucket上の更新したREADMEファイル

1.5 デプロイする

まだ第1章の途中ですが、この空っぽ同然のRailsアプリは既に本番環境にデプロイしようと思えばできる状態になっています。アプリケーションのデプロイは必須ではありませんが、頻繁に本番環境にデプロイすることによって、開発サイクルでの問題を早い段階で見つけることができます。開発環境のテストを繰り返すばかりで、いつまでも本番環境にデプロイしないままだと、アプリケーションを公開するぎりぎりの時になって思わぬ事態に遭遇する可能性が高まります22

かつてはRailsアプリの本番デプロイは大変な作業でしたが、ここ数年急速に簡単になってきており、さまざまな本番環境を選択できるようになりました。Phusion Passenger (ApacheやNginx23 などのWebサーバー用のモジュール) を実行できるさまざまな共有ホストや仮想プライベートサーバー (VPS) の他に、一通りのデプロイ環境を提供するEngine YardRails Machine、クラウドサービスを提供するHerokuなどがあります。

私のお気に入りはHerokuで、Railsを含むRuby Webアプリ用のホスティングプラットフォームです。Herokuは、ソースコードのバージョン管理にGitを使っていれば、Railsアプリケーションを簡単に本番環境にデプロイできます (Gitを導入したのは、まさにこのHerokuで使うためでもあります。まだGitをインストールしていない方は1.4を参照してください)。さらに、Herokuのfree tier プランには、チュートリアルでの利用を含むさまざまな用途のための機能が十分過ぎるほど備わっています。

この章では、最初のアプリケーションをHerokuにデプロイします。作業内容の一部に少しばかり高度な部分も含まれていますが、今はすべてを理解しておく必要はありませんのでご安心ください。今大事なのは、この章の終わりまで手順を進めることで、作成したアプリケーションを実際のWebサービスとしてデプロイすることです。

1.5.1 Herokuのセットアップ

Rails 5.1は現在サポート対象外となっており、Herokuにデプロイできない可能性が高いです。HerokuやAWS (S3) を使った本番環境へのデプロイについて学びたい場合は最新版に切り替えてお読みください。

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

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

HerokuではSQLiteがサポートされていないため、リスト 1.5の変更を行って、sqlite3 gemが本番環境に導入されないようにしておきます。

group :development, :test do
  gem 'sqlite3', '1.3.13'
  gem 'byebug',  '9.0.6', platform: :mri
end

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

リスト 1.13: 追加や並び替えを行ったGemfile Gemfile
source 'https://rubygems.org'

gem 'rails',        '5.1.6'
gem 'puma',         '3.9.1'
gem 'sass-rails',   '5.0.6'
gem 'uglifier',     '3.2.0'
gem 'coffee-rails', '4.2.2'
gem 'jquery-rails', '4.3.1'
gem 'turbolinks',   '5.0.1'
gem 'jbuilder',     '2.7.0'

group :development, :test do
  gem 'sqlite3', '1.3.13'
  gem 'byebug',  '9.0.6', platform: :mri
end

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

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

# Windows環境ではtzinfo-dataというgemを含める必要があります
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]

本番用のgem (この場合はpg gem) をローカルの環境にはインストールしないようにするために、bundle installに特殊なフラグ「--without production」を追加します (リスト 1.14)。

リスト 1.14: 本番用以外のgemをインストールする
$ bundle install --without production

リスト 1.13で追加したgemは本番環境でしか使わないので、このフラグを追加したコマンドを実行してもローカル環境には本番用gemは反映されません。ではなぜ今リスト 1.14のコマンドを実行したかというと、pg gemを追加したことをGemfile.lockに反映させないと、本番環境へのデプロイで失敗してしまうためです。これから行う本番環境へのデプロイを成功させるために、変更した内容のコミットも忘れずにおこないましょう。

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

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

$ heroku --version

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

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

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

$ heroku --version
heroku-cli/6.15.5 (linux-x64) node-v9.2.1

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

$ heroku login --interactive

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

最後にheroku createコマンドを実行して、Herokuサーバーにサンプルアプリケーションの実行場所を作成します (リスト 1.16)。

リスト 1.16: Herokuに新しいアプリケーションを作成する
$ heroku create
Creating app... done, fathomless-beyond-39164
https://damp-fortress-5769.herokuapp.com/ |
https://git.heroku.com/damp-fortress-5769.git

このherokuコマンドを実行すると、Railsアプリケーション専用のサブドメインが作成され、ただちにブラウザで表示可能になります。今はまだ何もありませんが、すぐにデプロイしてWebページを表示させましょう。

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

Railsアプリケーションを実際にHerokuにデプロイするには、まずGitを使ってHerokuにリポジトリをプッシュします。警告メッセージが表示されることもありますが、今は無視してください。詳しくは7.5で解説します。

Rails 5.1は現在サポート対象外となっており、Herokuにデプロイできない可能性が高いです。HerokuやAWS (S3) を使った本番環境へのデプロイについて学びたい場合は最新版に切り替えてお読みください。
$ git push heroku master

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

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

デプロイされたアプリケーションの表示は、heroku create (リスト 1.16) を実行した際に生成されたアドレスをブラウザで開くだけです (もちろんここに表示されている著者のアドレスではなく、あなたのアドレスを使ってください)。クラウドIDEではなくローカルコンピュータで作業している場合は、heroku openコマンドでブラウザ表示することもできます。実行結果を図 1.27に示します。ページの内容は図 1.19とまったく同じですが、今やそれがインターネット上の本番Webページとして堂々と公開されているのです。

images/figures/heroku_app_hello_world
図 1.27: 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を教えない限りサイトにアクセスされる心配もありません26。ちなみに、Rubyの威力の一端をお見せするために、サブドメイン用のランダムな文字列を生成するコンパクトなコードをササっと書いてみます。

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

最高ですね。27

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

演習

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

1.6 最後に

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

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

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

1.6.1 本章のまとめ

  • Ruby on Railsとは、Web開発のためのフレームワークであり、Rubyプログラミング言語によって記述されている。
  • 事前設定済みのクラウド環境を利用することで、Railsのインストール、アプリケーションの生成、生成されたファイルの編集を簡単に行うことができる。
  • Railsにはrailsという名前のコマンドラインコマンドがあり、rails newで新しいアプリケーションを生成したり、rails serverでローカルサーバーを実行したりできる。
  • コントローラのアクションを追加したり、ルートルーティングを変更したりするだけで「hello, world」アプリケーションを作成できる。
  • Gitによるバージョン管理を導入し、Bitbucketの非公開リポジトリにプッシュする理由は、データの喪失を防止し、他の開発者との共同作業を行えるようにするため。
  • 作成したアプリケーションをHerokuの本番環境にデプロイした。
1. 他にも水産物流貿易医療法務無人管理VR業界などでも採用され、2023年12月には宇宙ビジネスでも上場しました。各分野の活用事例はRuby AssociationのWebサイトから確認できます。
2. Railsの設計哲学の詳細は「The Rails Doctrine(日本語訳)」からお読みいただけます。
3. Hotwireについては本チュートリアル完走者を対象とした「読み物ガイド」や、Rails 7の推しポイントを解説したYouTube動画などでも紹介されています。
4. 例えば世界中から技術者・研究者が集まるGoogle Brainチームでも、15分ルール(何かに詰まった時、まず自分で15分解決を試みなさい。そして、15分経ったら、他の人に助けを求めなさい。)が採用されています。
5. 例えばfooという名前のメソッド定義を見つけるには、「def foo」をグローバル検索します。
6. AWSのサイトは継続的に更新されているため、詳細な手順は異なっているかもしれません。コラム 1.2の「熟練」の考え方を参考に細かな差異にも対応してみましょう。
7. もしこのコマンドに興味のある方はman printfを使ってprintfを調べてみてください。詳しくは コマンドライン編でも説明されています。
8. 「熟練」の典型的な例と言ってよいでしょう (コラム 1.2)。
9. 同様にして、~> 4.0と指定するとバージョン4.9のgemがインストールされる可能性はありますが、5.0がインストールされることはありません。この指定法は、gemのプロジェクトがセマンティックバージョニング (略称: semver) と呼ばれる方式でバージョン番号を管理している場合、特に便利です。セマンティックバージョニングとは、ソフトウェア同士の依存関係を壊さないよう変更を最小限にしてリリース番号を与える方法です。
10. 表 3.1に示したように、実はinstallを省略できます。bundleコマンドそれ自体がbundle installのエイリアスであるためです。
11. ここで「C」はキーボードのキーを指します。大文字という意味ではありませんので、Shiftキーも押す必要はありません。
12. 本チュートリアルで使っている図中のCloud9のURLは、rails-tutorial-c9-mhartl.c9.io からAWS上の特定のURLに変更されています。スクリーンショットを撮った時点と現時点との合間にURLの規則が変わる可能性がありますが、都合上、元のままにしています (図 1.19)。この程度の小さな不一致であれば自力で解決できるぐらいのスキルを、一緒に本チュートリアルで身につけていきましょう (コラム 1.2)。
13. 利用しているエディタによっては「invalid multibyte character」といったエラーメッセージが表示されることがあるかもしれませんが、気にする必要はありません。このメッセージを表示しないようにする方法が知りたい場合は、エラーメッセージでググってみてください。
14. Web上から無料で読める書籍としては Pro Git が有名です
15. チュートリアル本編ではこのファイルを修正することはありませんが、3.6.gitignoreファイルへの追加例があります。これは、3.6で行うオプションの詳細テスト設定の一部です。
16. ここではデフォルトの[Untitled project] を選択していますが、任意のプロジェクト名を入力することも可能です。
17. 指定しない場合、デフォルトのブランチ名はmasterとなります。
18. 著者がCloud9で公開鍵を設定したときの都合上、railstutorialというリポジトリを作成してから著者のメインアカウント(mhartl)をcollaboratorとして追加してあります。そうした経緯があったので、著者はどちらのアカウント名でもコミットできるようになっているのです。
19. Markdownの詳細は テキストエディタ編Git/GitHub編をご覧ください。
20. Gitリポジトリをビジュアル表示するには、AtlassianのSourceTreeアプリケーションが便利です。
21. 第6版から採用されているGitHubでは、public/privateを問わず人数の制限なしにリポジトリを共有できます。共同開発については Git/GitHub編4章「Gitで共同作業する」 の例などをご覧ください。
22. Railsチュートリアルのサンプルアプリケーションでは気にする必要はありません。作りかけの恥ずかしいWebアプリケーションをネットにうっかり公開してしまわないだろうかと心配する方もいらっしゃるかと思いますが、それを防ぐための方法はいくつもありますのでご安心ください。1.5.4はその方法の1つです。
23. “Engine X" と発音します。
24. 一般的に、開発環境と本番環境は、データベースも含めてなるべく同じにしておく方が便利です。しかし本チュートリアルでは、教育的見地からあえてローカルではSQLite、本番ではPostgreSQLを使うようにしています。詳細については3.1を参照。
25. Herokuアカウントに2要素認証の設定をしている方は、パスワードではなくAccount settingsからAPI Keyをコピーして入力してください。
26. このソリューションは通称「あいまいさを利用したセキュリティ」と呼ばれ、ホビー目的程度であれば十分有効です。最初からもっとまともなセキュリティを導入したいのであれば、RailsのHTTP BASIC認証の利用をオススメします。とはいえ、BASIC認証の実装はやや込み入っているので、それなりの熟達したスキルが必要となります (コラム 1.2)。また、この問題を指摘してくれたAlfie Patesに感謝いたします。
27. Rubyではよくあることですが、実はもっとコンパクトになるんです。今回の例では、Rubyのsampleメソッドを使うことで ('a'..'z').to_a.sample(8).join と書くこともできます。指摘してくれた読者のStefan Pochmannに感謝! 著者もまた新たなRubyの一面に触れられました。
28. メーリングリストもあります。 railstutorial.jp/#news
前の章
第1章 ゼロからデプロイまで Rails 5.1 (第4版)
次の章