Ruby on Rails
入門5
- 前回のまでで、基本の機能【 CRUD 】について学び、【 newファイル 】【 editファイル 】を作成し、コントローラにはアクションメソッドを用意したところでした。
- さっそく続きをやっていきましょう。
前回の確認
- では、まずは作成した【 newファイル 】【 editファイル 】を、とりあえず以下のように編集してください。
仮のビューファイルを作る
editファイル( app/views/books/edit.html.erb )
newファイル( app/views/books/new.html.erb )
- もちろん、これで完成というわけではなく、後でしっかり作っていきます。
- まずは「それぞれのページに、アクセス(表示)できるようにする設定」を先にしていきます。
- 表示されるためには、以下の動きが必要でした。
- 「サイトを見る人(ブラウザ)」からの「リクエスト(要求)」があった時に、適切なコントローラのメソッド(アクション)へのルートを用意する。
- ルートに対応したコントローラーが、データをデータベースから取得し、それを元にビューを渡す。
- ビューが、データを元にHTMLを作る。
- つまり「ルーティング」「コントローラ」「ビュー」の順番になりますので、この順番通りに作っていきましょう。
- まずはルート設定からです。次へ。
- ルート設定と言えば【 routesファイル 】ですね。
- ここに、newページ と、editページ 用のルートを作ります。以下のように編集してください。※コメント部分は削除しています。
- URLの末尾に「 /books/new 」が付いていれば、booksコントローラ の newメソッド が実行され、
- 「 /books/edit/パラメータ 」が付いていれば、booksコントローラ の editメソッド が実行される、という設定ですね。
- editに関しては「 どの本を編集するのか? 」という指定が必要なため、show と同じようにパラメータ(id)を指定しています。
routesファイル
- 試しに、ページを表示してみましょう。
- これでルート設定(ルーティング)がうまくいっていることが確認できました。
- 尚、editページですが、まだ「パラメータによって、表示内容を変える」ということはしていないので、どんなパラメータを指定しても同じページが開きます。
routesファイル
editページ
newページ
- では次は、コントローラーの設定です。
- booksコントローラー( app/controllers/books_controller.rb )を以下のようにしてください。
- ※今回変更する箇所は、newメソッド と editメソッド だけですので、それ以外のコードは下の画像には、のせてません。
- ※ただ省略しているだけなので、削除したりはしないでください。newメソッド と editメソッドの部分だけ変更してください。
- newメソッド の「 Book.new 」の部分は、「新しいレコードを作る」という意味です。それが @book に代入されます。
- つまり、@book の中身は、まだ中身が空っぽのレコード(1冊の本のデータ)という感じです。
- ※正確には、現時点では Bookクラスのインスタンスというものが作成されています。
- ※データベースに保存(.save)してからレコードになります(保存しなかった場合は、インスタンスは削除されます)
- editメソッドに関しては showメソッド とまったく同じですね。
- URLで指定したパラメータを元に、データベースの idカラム から、レコード(1冊の本)を持ってくるという意味です。
コントローラ
editメソッド
newメソッド
- 最後はビューを変更します。
- 今回作る newページ と editページ は「データをデータベースに登録するため」のページです。
- 今まで作った indexページ と showページ は「データを表示するだけ」でした。ここが大きく違う点です。
- 「データをデータベースに登録するため」のページは、基本的に「 form(フォーム)」があります。→の画像のように、サイトを見る人が、何かしらを入力するような画面のことです。
- HTMLだと <form>タグ を使って、フォームを作りますが、Railsでは専用のコードが用意されており、それを使ってフォームを作るのが基本です。
- では、まずは newページ から作っていきましょう。次のページへ。
ビュー

- 「 app/views/books/new.html.erb 」を以下のように変更してください。
ビュー
- 「 form_with 」がフォームを作成ために、Railsで用意されているメソッドです。(ヘルパーメソッドという)
- ※フォームを作るメソッドは色々ありますが、基本的には form_with を使います。(Railsのバージョン4以前は、form_forが基本でしたが)
- ()の中の引数部分は細かくなるので、また後で説明します。
- とりあえず、これでページを確認してみましょう。次へ。
- ちゃんと表示されたらOKです。※まだ、登録を押してもエラーになります。
ビュー
- 今は入力できるのが「タイトル」だけですよね?
- 他にも「読んだ日(dateカラム)」や「評価(starカラム)」や「感想(impressionカラム)」が bookモデルにはあります。
- それもフォームから登録できように、フォームを変更しましょう。
- ※もし、出来そうならチャレンジしてみてください。とりあえずは下のような表示になればOKです。
- 答えは次のページ。
- 以下のように変更したら良いですね。※カラム名の部分など間違いやすいので、注意してみておいてください。
ビュー
- また、どのコードが、画面のどこにつながるのか、なんとなくで良いので意識しておいてください。
ビュー
- さらに改良します。
- 入力欄(フィールド)が横に並んでいると使いづらいので、縦に並べるために<p>で囲んでおきます。
- かなり適当なHTMLですが、今はRailsの方に集中したいので、気にしないで行きましょう。
ビュー
- 大体今はこんな感じの画面になっていると思います。
ビュー
- 今はすべて「文字」で入力するフィールド(text_field)のため、ちょっと使いにくいです。
- 「読んだ日」はマウスで日付を選択できた方が良いですし、「感想」は1行だけだと短すぎるので、もっと入力フィールドが大きくないと使いにくいですよね?
- ということで、さらに改良します。次のページへ。
- 以下のように変更してください。※書いてない部分は省略しているだけなので、消さないでください。
ビュー
- このように変更できたら、再度ページを確認してみましょう。次へ。
- 以下のようになればOKです。実際にフォームを触ってみてください。
ビュー
- このようにRailsでは必要に応じて、色々なタイプのフィールドを作れるようになっています。
- ※他にもまだまだありますが、とりあえず今はいっぱいある、ということをわかっていればOKです。
- では、とりあえずビューに関してはOKとすることにして、実際に「登録」ボタンを押した時に、データベースに登録できるようにするためにはどうするか?という話に進みましょう。
- まぁ詳しい説明の前に、一旦フォームの「登録」ボタンを押してみましょう。以下のようなエラーになるはずです。
ビュー
- 「Routing Error」(ルーティング エラー)と出ていますね。
- 「ルーティングってことは、ルート設定がおかしいのかな?」っと思った人は素晴らしいです。よくわかっています。
- そう、これはルートがわからない(どこのコントローラーのメソッドで処理させるかわからない)ためにエラーが起きています。
- 実はフォームというのは、基本的に登録ボタン(実際には送信ボタン)を押すと、入力したデータを送信すると同時に「どこかのURLを開く(遷移:せんい と言う)」処理が動きます。
- その時に「どこに行っていいかわからない」という状態が今です。次へ。
- では、この「どこのURLに行くか」の設定は、どこにあるかと言うと、先ほどのコードの以下の部分になります。
ビュー
- 「 url 」って書いてますもんね。
- じゃあ url の右の「 book_index_path 」とはなにか?というと「 ~/books/index 」の事です。
- 結構前に作ったきりの、indexページです。→のページ
- Railsでは「 ~/books/index 」なら「 book_index_path 」みたいに、別名が付けられています。
- ルートヘルパーメソッドといって、URLの指定を便利にするもので、変数みたいな感じで使います。
- (長いので、以後ルートヘルパーと呼びます)
- 新しい本を登録した後は、この「本の一覧ページ(indexページ)」に行く、という設定なわけです。
- この設定自体は別に良いはずなのですが、なぜルーティングエラーになるのでしょうか?
- 「 ~/books/index 」のページは、普通にアクセスできるはずですよね?
- これの答えが「HTTPメソッド」というものになります。次へ。
- 「HTTPメソッド」が何かと言うと、サイトを見る人(正確にはブラウザ:クライアントともいう) が サーバ(今回はRails)にお願いする時の「お願いの種類」のことです。
- 例えば、ただ「このURLのページを見せて」という「お願いの種類」なら「 get 」(ゲット)というHTTPメソッドを送信します。
- 今回のように「データを登録して」という「お願いの種類」の場合は、一般的に「 post 」(ポスト)というHTTPメソッドを送信します。
- このように HTTPメソッドとは「お願いの種類」に応じて、適切に使いわけられています。
- ※もう少し正確にいうと、「データベースに登録して」という場合も get を使うことは出来ますが、get は登録するデータが丸見えになるため、セキュリティの都合で post を使います。
- HTTPメソッドは色々な種類がありますが「 get 」「 post 」と「 patch 」(パッチ:部分更新)「 delete 」(デリート:削除)を主に使います。
- このHTTPメソッドが、どこで設定されているかと言うと、先ほどのコードの以下の場所です。
HTTPメソッド
- method(メソッド)と、post て書いてますよね?
- では、今度はルート設定を確認しなおしてみましょう。次へ。
- ルート設定と言えば「 config/routes.rb 」です。今は以下のようになっています。
HTTPメソッド
- get という文字が books/index の所に書いてますよね?
- これは「 get メソッドで、/books/index にアクセスがあった時」という意味になります。
- つまり「 post だった場合 」のことは何も書かれていないのです。
- だからルートがわからずにルーティングエラーになっています。
- じゃあ post のルートも追加してあげましょう。次へ。
- 以下のように post でも /bools/index に行けるようにルートを追加してください
ルーティング
- ルートが出来たので、もう一度登録ボタンを押して、試してみましょう。
- ※とりあえず本の名前とかは、aaaみたいにしておいてください。
- エラーにはならず、ちゃんと indexページが開くはずです。→
- 次のページへ。
- ふー良かった良かった、と思うのはまだ早い!
- 実はまだデータは登録されていません!(indexページも何も変わってないですよね?)
- そう、ただ indexページが開くようになっただけで、登録の処理はなにもしてないからです。当然データベースにも登録されません。
- 少し話をさかのぼってみると、新規登録をするために「 createメソッド 」というのを用意したのを覚えているでしょうか?
- これがまったく使われていませんね。今度はこの createメソッド を使って「データを新規登録する」ということをやっていきます。
- つまりフォームの「登録」ボタンを押したら、すぐに indexページ に行くのではなく、先に「 createメソッド 」を実行してから、indexページを開く、という流れになります。
- とりあえず、ルート設定をやり直します。以下のようにしてください。
ルーティング
- これで「postメソッドで、/books/index のURLが指定された場合は、booksコントローラーの createメソッドを実行する」というルートになりました
- 次は createメソッド を作っていきます。
- ここでは「フォームから送信されてきたデータを受け取って、データベースに新規登録する」という処理が必要ですね。
- 以下のようにしてください。※ createメソッド 以外は画像にのってないですが、消してはいけません。
createメソッド
- これはまだ途中段階ですが、以前、初期データを登録するときに seedファイル というのを作ったと思いますが、それと同じ書き方です。
- 最初に @book = Book.new で新しい bookクラス のインスタンス(セーブしたらデータベースのレコードになる)を作り、そのカラムに、名前や日付などを入れて、最後に @book.save で保存する、という流れです。
- 今は、= の右側部分が空白ですが、ここにフォームから送信されたデータが入ることになります。次へ。
フォームから送信されてくるデータを指定する
- つまり後はフォームから送信されてくるデータを、どうやって取得すれば良いか?ということだけです。
- フォームから送信されてくるデータは、params(パラムズ)に入れられているので、そこから取り出す、ということになります。
- params は、URLの末尾につけたパラメータも入っていましたね。
- Rails では、様々な送信データのやり取りは基本的に params を使って行います。
- では、今回はどのように取り出せば良いか?というと、以下のように書きます。
createメソッド
- あまり馴染みのない書き方かもしれませんが、フォームから送信されてくるデータを取得するには「 params[:モデル名][:カラム名] 」と書きます。次へ。
ハッシュのネスト構造
- この「 params[:モデル名][:カラム名] 」という書き方は、ハッシュが2重になっている構造です。
[:book]
params
ハッシュ
book
ハッシュ
[:id]
[:name]
[:date]
[:star]
[:impression]
これが「:book」に入っている(紐づいている)
- つまり「 params[:book][:name] 」の場合は「 params[:book]の中の、(つまりbookハッシュの)[:name] 」という指定になります。
- フォームを使って送信した場合、このような形で、params に入れられます。
- これでデータの新規登録はOKです。ただ試す前に、もう一つやることがあります。
- 登録した後に、結局どのページを開くのか?というのが決まっていません。
- ルート設定の「post 'books/index' => 'books#create'」という設定は、この createメソッド を実行する、という設定であって、indexページを開く設定ではありません。
- なので、データの保存後に、再度indexページを開く処理を書きます。それが以下です。
createメソッド
- 「 redirect_to ルートヘルパー(URL)」と書けば、そのルートへ、get メソッドでアクセスしてくれます。
- つまりルート設定の「 get 'books/index' 」へ、アクセスされます。ここまで出来たら、実際に本を登録してみましょう。
- フォームから登録後、indexページに本が追加されていれば成功です。
createメソッド
- これで「新規作成」、CRUDの内「 C(create)」は完了しました。後は「U」と「D」だけですね。
- では、「U(update)」を作っていきます。
- これは、すでに登録している本のデータ(レコード)の「編集」のことでしたね。
- まずは editページ を仕上げていきたいと思いますが、実は newページ とほとんど同じでので、コピペを活用してください。
- 次のページへ。
editファイル
- editファイルを以下のようにしてください。
editファイル
newファイルと違う点は
赤線の3か所だけです。
book_update_path(@book)に関しては、
次のページで解説します。
- url として設定した「 book_update_path(@book) 」なのですが、実はまだこのルートヘルパーは存在していません。(なのでエラーになります)
- newファイルの時に使った「 books_index_path 」というルートヘルパーは、Railsが勝手に作ってくれていたのですが、すべてのヘルパーを作ってくれるわけではないので、必要なものは自分で作ります。
- 作る場所は、ルートの設定なのでもちろん「 routes.rb 」です。以下の箇所を追加してください。
ルート設定と、ルートヘルパー設定
- 赤枠の部分が通常のルートの設定です。patch メソッドで「 ~books/パラメータ 」のURLにアクセスがあれば「 booksコントローラーの、updateメソッド 」にルートを作っています。ここまでは、new の時と同じ感じです。
- 青枠の部分が「ルートヘルパー」を設定している部分です。これで「 books_update_path(:パラメータ) 」というルートヘルパーが使えるようになります。 次へ。
- また、update だけじゃなく、showページに対してルートヘルパーも自分で作らないといけないため、先に設定しておきます。
- ※(「編集」が完了した後は、編集した本の show ページを表示する予定なので)
- showに関しては、すでにルート設定はあるので、ルートヘルパーの設定だけ追加します。
ルート設定と、ルートヘルパー設定
- これで「 book_show_path(:パラメータ) 」とすれば、指定した本の showページ が開くようになります。次へ。
- 最後にコントローラーの「 updateメソッド 」を完成させましょう。以下のようにしてください。
- これも、大部分が createメソッド と同じなので、コピペを活用してください。
updateメソッド
- createメソッドと違い、新しいレコード(インスタンス)を作るのではなく、編集したいレコードのデータを「 Book.find_by(id: params[:id]) 」で取得しています。
- また、「 redirect_to books_show_path(@book) 」で編集した本のshowページにアクセスしています。
- ※(@book)の所は、本来 id番号を指定するところですが、@bookだけで、@bookのid情報を取り出してくれます。
- つまりは省略した書き方で、もし省略せずに書くと(@book.id)になります。
- では、実際に編集できるか確かめてみましょう。
- editページを表示するには「 ~/books/edit/id番号 」となります。
- おそらく、今は最低4つの本が登録されていると思うので、id番号として、1から4のどれかを指定し、何か変更して試してみましょう。
updateメソッド
ここでは、id番号 1 の本のタイトルを編集しています
ちゃんと編集されていればOK
- ちなみに、ルート設定や、ルートヘルパーの設定を確認する方法を紹介しておきます。
- 色々あるのですが、一番簡単で見やすいのが「ルーティングエラー」の画面です。なので、わざとエラーを出して確認するのもありです。
ルートの確認方法
ルートヘルパー
HTTPメソッド
URL(Path:パスとも言います)
対応するコントローラー#メソッド
何も書いてない所は
ルートヘルパーが未設定のルート
- 以上で、CRUDの内、CRUまでが終わりました。後は「D(delete)」だけです。
- これは専用のページはいらないので、editページに「削除ボタン」を用意すれば良さそうです。
- delete に対応するコントローラーのメソッドは destroyメソッド でしたね。これを作っていきます。
- 「 app/controllers/book_controller.rb 」の destroyメソッド を以下のようにしてください。
destroyメソッド
- 今までのメソッドに比べて、非常にシンプルですね。
- 最初に、削除したいbookのレコードを持ってきて、それを「 @book.destroy 」で削除しています。
- 削除に関してはこれだけです。
- その後、indexページを開いています。
- 後は、このdestroyメソッドを実行すれば良いだけです。次へ。
- この destroyメソッド を実行する方法も、基本的には今までと同じで「どこかのURLから、コントローラーのメソッドへのルートを作って、そのルートにアクセスすることで、メソッドを実行する」ということです。
- ただ、今回は専用のページはありませんので、editファイル(app/views/books/edit.html.erb)に以下のコードを追加してください。
場所は、ファイルの一番下
※必ず<% end %>よりも下に作る事。
<% end %>よりも上になると、フォームの中に入ってしまうため、編集しようとしても、削除になってしまう、ヤバイバグになります。
拡大版
destroyメソッド
- 説明です。
destroyメソッド
- button_toは、HTMLのbuttonタグを作るヘルパーメソッドです。
- これに、URL(パス)として「 book_destroy_path(@book) 」と、HTTPメソッドとして「 delete 」を設定しています。
- まだこのルートや、ルートヘルパーはないので、それを作れば完成です。
- 次へ。
- 以下のように追加してください。
destroyメソッド
- これでルート設定と、ルートヘルパーが設定できました。
- 実際に試してみましょう。
- ※削除すると戻せないので、消えても良い本の編集ページを開き、削除してください。
- 以下のように赤線部分を追加してください。
destroyメソッド
indexページを見ると、
ちゃんと消えてればOK
お疲れ様でした
- これで、CRUDの機能すべてが追加できました。
- 次はもう少し操作しやすいサイトを目指して、「ルートの見直し」や「サイト内リンク」を作っていきたいと思います。
- 続きは次回のスライドで。
Ruby on Rails入門5
By kinocode
Ruby on Rails入門5
- 1,269