Railsの教科書

top

CRUDの基礎とindexアクション

Webアプリには基本となる4つの機能があります。ページの新規作成(Create)、表示(Read)、更新(Update)、削除(Destroy)です。それぞれの頭文字を取ってCRUDと呼ばれています。大きなWebアプリも、このCRUDを基礎として作られます。

ここではCRUD機能を持ったRailsアプリを作り、その動作について解説します。

CRUD基礎

アプリの作成

今回も最初にアプリを作ります。本のタイトルとメモを管理する簡易なアプリです。以前の章で作成した my_web_apps フォルダの下に新しいアプリを作ります。ターミナルを起動して以下のコマンドを打ちます(メッセージ中の"Done in 3.61s."の数字は所用時間なので、毎回異なります)。

cd my_web_apps
rails new books_app
$ rails new books_app
      create
... (略)
   Done in 3.61s.
Webpacker successfully installed 🎉 🍰

次に、以下のコマンドを実行します(メッセージ中"in process 52142"、"20160702024137"、"-> 0.0013s"などの数字は実行するごとに異なります)。

cd books_app
rails g scaffold book title:string memo:text
rails db:migrate
rails s
$ rails g scaffold book title:string memo:text
Running via Spring preloader in process 20280
      invoke  active_record
      create    db/migrate/20191012005727_create_books.rb
...
      invoke  scss
      create    app/assets/stylesheets/scaffolds.scss

$ rails db:migrate
== 20191012005727 CreateBooks: migrating ======================================
-- create_table(:books)
   -> 0.0034s
== 20191012005727 CreateBooks: migrated (0.0035s) =============================

$ rails s
=> Booting Puma
...(略)
* Listening on tcp://localhost:3000
Use Ctrl-C to stop

ブラウザを起動して以下のURLを入力してアクセスしてみます。

起動した画面

こんな画面が表示されましたでしょうか。ここから、New Bookリンクをクリックして先へ進み、title欄とmemo欄を記入しCreate Bookボタンを押してみてください。

TODO: 入力画面のスクショを足す。ベストは文字列が入力されている状態。system specで書けると楽でいい。 TODO: 本の情報を学習ガイドにする

データを入力してCreate Bookボタン

ここからBackボタンを押すと最初の/booksのページに戻りますが、先ほど入力したデータが表示されていることが分かるかと思います。

入力したデータが表示される

さらにデータを追加したり、他のリンクも操作してみてください。

ここで作成したアプリはCRUDの各機能、すなわち、新規作成、表示、更新、削除を持っています。以降で、1つずつその動作を説明していきます。

scaffoldコマンド

ここまで何回か出てきたrails g scaffoldコマンドは新規作成、表示、更新、削除、各機能を一度に作る機能です。つまり、scaffoldを使うとCRUD機能を持ったページを作成することができます。

scaffoldは英語で「(建築現場などの)足場」という意味です。工事中の建物のまわりに組まれた足場の上で大工さんが作業している、あの足場です。scaffoldコマンドはWebアプリを作り易くするための足場です。CRUD機能はWebアプリでよく使う機能なので、「CRUDのこの部分にこの機能を足したらできるな」という場合に、scaffoldで生成したファイル群を編集して自分のアプリを作っていくと効率良く作れます。

作成されるファイルは以下の通りです。

$ rails g scaffold book title:string memo:text
Running via Spring preloader in process 20280
  invoke  active_record
  create    db/migrate/20191012005727_create_books.rb
  create    app/models/book.rb
  invoke    test_unit
  create      test/models/book_test.rb
  create      test/fixtures/books.yml
  invoke  resource_route
   route    resources :books
  invoke  scaffold_controller
  create    app/controllers/books_controller.rb
  invoke    erb
  create      app/views/books
  create      app/views/books/index.html.erb
  create      app/views/books/edit.html.erb
  create      app/views/books/show.html.erb
  create      app/views/books/new.html.erb
  create      app/views/books/_form.html.erb
  invoke    test_unit
  create      test/controllers/books_controller_test.rb
  create      test/system/books_test.rb
  invoke    helper
  create      app/helpers/books_helper.rb
  invoke      test_unit
  invoke    jbuilder
  create      app/views/books/index.json.jbuilder
  create      app/views/books/show.json.jbuilder
  create      app/views/books/_book.json.jbuilder
  invoke  assets
  invoke    scss
  create      app/assets/stylesheets/books.scss
  invoke  scss
  create    app/assets/stylesheets/scaffolds.scss

この中のroute(invoke resource_route), controller(invoke scaffold_controller)やview(invoke erb)は前の章で説明したrailsの各役割を担うファイルです。

一方、ページの観点から見ると、scaffoldは次に示す新規作成、表示、更新、削除のための4つの画面と、画面のない3つの機能を生成します。

CRUD 4つの画面

それぞれの機能と対応するアクションを示したものが次の図です(アクションとはコントローラに書いてあるpublicなメソッドのことです)。基本的には、1つの画面を表示するとき、1つのアクションが実行されています。アクションについてはまた後で説明します。

CRUD 7つのアクション

この中から最初に、indexアクションのページについて見ていきましょう。

indexアクション

最初にindexアクションについて見ていきましょう。さきほどの7つのアクションの図で示されたこの部分です。

indexアクション

indexアクションで表示されるページ(下の図)は登録されているデータの一覧です。ここでは登録されているBookの一覧表示画面になります。この画面が表示されるまでの処理を追いかけてみましょう。

TODO: データを学習ガイドと超入門に置き換え

index - 一覧画面

前にも出てきた「Railsアプリがリクエストを受けてレスポンスを返すまで」をindexアクションの場合で描きなおした図が以下になります。

Railsアプリがリクエストを受けてレスポンスを返すまで(indexアクション)

順番にRoutesから処理を追っていきます。

Routes

Routesはリクエストと処理を行うコントローラを決めるための対応表です。

Routes

Routesでリクエストから次に処理するコントローラとアクションが決まります。routes対応表を表示するために、rails serverを起動して、http://localhost:3000/rails/info/routes へアクセスしてみましょう。

Routes対応表

今回はURLが"/books"、HTTPメソッドが "GET" なので、下線部が該当行です。「/booksにGETでアクセスされたとき、BooksControllerのindexアクションへ処理を流す」という意味になります。次に進むべきコントローラはbooks#index(BooksControllerのindexアクション)となることが分かります。

コントローラの処理を見る前に、Routesのコードを見てみましょう。Routesのコードは config/routes.rb にあります。コードは以下のようになっています。

Rails.application.routes.draw do
  resources :books
  # For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html
end

Routes対応表を作るコードは Rails.application.routes.draw do から end の間に書きます。#記号ではじまる行は分かりやすさのためのコメントで、動作には影響がありません。 http://localhost:3000/rails/info/routesのページで表示された8行の対応表は、resources :books の1行によって作られます。CRUDは基本的な動作でよく利用されるため、簡単に書けるようになっているのです。

それでは次の処理、コントローラへ進みましょう。

コントローラ

Routesではリクエストから処理されるコントローラとアクションが決まると、次はコントローラへ処理が移ります。今回はBooksControllerのindexアクションです。

コントローラ

コントローラのコードを見てみましょう。ファイルは app/controllers/books_controller.rb です。

class BooksController < ApplicationController
  ...
  def index
    @books = Book.all
  end
  ...

class BooksController < ApplicationControllerから最後の行のendまでがBooksControllerのコードです。この中のdef indexから次のendまでがindexアクションになります。

ここでやっていることは1行、@books = Book.all です。Book.allでBookの全データが詰まった配列を取得して、@booksインスタンス変数へ代入します(Book.allでBookの全データがとれる仕組みについては、「モデル」の章で説明します)。

@booksは@から始まる変数、インスタンス変数です。「一番小さなRailsアプリつくり」のところでも説明したように、インスタンス変数@booksを使っているのは、次に処理を行うviewで利用するためです。もしも、ここで変数をローカル変数booksにしてしまうと、コントローラの処理が終わったところでなくなってしまいます。

また、@bookと単数形ではなく@booksと複数形になっているのはBook.allで取得するデータが複数の本のデータを格納した配列であることを示すためです。場合によっては、本のデータが1つしかない、あるいは0個である、という状況も考えられます。その場合も1個、あるいは0個のデータを格納した配列が取得されます。どのパターンも@booksは配列を指すため、変数名を複数形の@booksにするのが慣習です。細かいことのようですが、RailsやRubyでのプログラミングでは変数の複数形と単数形を意識して命名することは大切なことです。

コントローラのアクションでの処理が終わると、次はビューに処理が移ります。特に指定がない場合、app/views/コントローラ名/アクション名のviewファイルへ処理が移ります。ここではapp/views/books/index.html.erbです。

ビュー

最後はビューでレスポンスとして返されるHTMLがつくられます。

ビュー

ビューのコードを見てみましょう。今回は app/views/books/index.html.erb です。

TODO: 置き換え

ビューのコード

コントローラで取得した@booksを表示させる箇所を見てみましょう。表示は<% @books.each do |book| %>から<% end %> で行っています。@booksに代入された全データ("ドラえもん"、"君に届け")でブロックを繰り返し実行し、titleやmemoを表示したり、show(詳細画面)やedit(編集画面)、削除ボタンのリンクを生成します。

図に示した状態では、@booksに2つのデータが入っています。@books.each文は全データで繰り返し処理を行う文です。1回目の実行では変数book(2つの|記号で囲まれている所)にドラえもんのデータが入った状態でtitleやmemoが表示されます。2回目の実行では君に届けのデータが格納されて同様の処理が実行されます。

index.html.erbはHTMLのテンプレートファイルで、HTMLの中にRubyコードを埋め込むことができます。<%= %>で囲まれたコードは評価結果がHTMLとして出力されます。<% %> で囲まれたコードは結果が出力されずに実行されます(今回は@books.eachの繰り返しで <% %> が使われています)。

RailsアプリはつくられたHTMLをレスポンスとしてブラウザに返します。ブラウザは受け取ったHTMLを私たちが見れる形で表示します。

まとめ

この章ではCRUDの1つ、一覧表示(index画面)の基礎的な内容について説明しました。

リクエストを受けてレスポンスを返すまでの流れをまとめると以下のようになります。Railsアプリはリクエストを受けると、 Routes、コントローラ、ビューの処理を経てレスポンス(HTML)を返します。

Railsアプリがリクエストを受けてレスポンスを返すまで(indexアクション)

今回のリクエストはindex(一覧)画面を表示するものです。上記の処理の後、ブラウザは受け取ったHTMLを私たちが見れる形で表示します。

index画面

ポイントをまとめると以下のようになります。

次の章ではCRUDのCreate(新規作成)について説明します。

さらに学びたい場合は