Rails Ambassador

コントローラの作成

このLessonではコントローラについて学習していきます。
コントローラもモデル同様Classです。コントローラに書かれているPublicなインスタンスメソッドの事をactionと言います。

コントローラの命名規則

モデルを操作するためのコントローラ名は必ずModelの複数形で全て小文字にしましょう。resourcesのルーティングと相まってコード記述をシンプルにすることができます。
また、モデル名が複数単語である場合は全て小文字で単語をアンダースコアで区切るスネークケースという記法にし、最後の単語を複数形にしましょう。

UserPostモデルを操作するコントローラ
=> user_posts_controller.rb

※モデルを操作しないコントローラ名は任意の名称で大丈夫です。

コントローラの作成

コントローラ作成の構文は以下になります。

$ rails generate controller コントローラ名 

もちろんgenerateを短縮形にすることができます。以下も同様に動作します。

$ rails g controller コントローラ名 

コントローラの削除

$ rails destroy controller コントローラ名 

以下も同じ処理になります。

$ rails d controller コントローラ名 

こちらの削除コマンドを実行することで、自動生成されたファイルやルートも削除されます。

postsコントローラを作成する

基本がわかったところでコントローラを作成しましょう。
Postモデルを操作するためのコントローラ名はモデル名の小文字複数形のpostsコントローラにしましょう。

$ rails g controller posts
      create  app/controllers/posts_controller.rb
      invoke  erb
      create    app/views/posts
      invoke  test_unit
      create   test/controllers/posts_controller_test.rb
      invoke  helper
      create    app/helpers/posts_helper.rb
      invoke    test_unit
      invoke  assets
      invoke    coffee
      create      app/assets/javascripts/posts.coffee
      invoke    scss
      create      app/assets/stylesheets/posts.scss

create表示になっているものが自動で生成されているファイルになります。
app/controllers/posts_controller.rbがコントローラ本体となり、同時にコントローラと同じ名前のhelper、JavaScriptファイル、SCSSファイルが生成されることも覚えておきましょう。 そしてviewsにもコントローラと同名のディレクトリ「app/views/posts」ができていることも重要なポイントです。

投稿一覧ページの作成

それでは投稿一覧ページを作成していきましょう。
resourcesのルーティングで学習したように、一覧ページはindexアクションであると学習しました。

参考: resourcesで生成されるアクションについて

それではindexアクションから作成していきます。
app/controllers/posts_controller.rbを開いて以下のように編集して保存してください。

class PostsController < ApplicationController
  def index
    @posts = Post.all
  end
end

indexアクションというのはコントローラ(Class)のインスタンスメソッドのことです。
この中にインスタンス変数@postsを定義しました。インスタンス変数名は任意のもので結構ですが、Postモデルの全てのインスタンスが入るPost.allの結果を代入するものなので、複数形の@postsとしています。
インスタンス変数名はすべて小文字で、単語の区切りを_で繋ぐスネークケース(snake_case)という記法にすると良いでしょう。class名の様に大文字から始めて(UpperCamelCase)はいけません。

では次にviewを作成しましょう。アクションに対応するデフォルトviewのファイルは規則があります。

app/views/コントローラ名/アクション名.html.erb

よってposts#indexのviewは 「app/views/posts/index.html.erb」ファイルとなります。
このファイルを作成し、内容を以下のようにして保存してください。

<h1>みんなの投稿一覧</h1>
<% @posts.each do |post| %>
  <%= post.content %><br>
<% end %>

記載できましたらサーバを起動してposts#indexのルーティングになっているURIへアクセスしましょう。
resourcesで生成されるルートを覚えていない方はルートを確認してください(覚えていない方はこちらを暗記できるようになっておきましょう。)。

$ rails routes

Prefix    Verb   URI Pattern               Controller#Action

posts     GET    /posts(.:format)          posts#index
          POST   /posts(.:format)          posts#create
new_post  GET    /posts/new(.:format)      posts#new
edit_post GET    /posts/:id/edit(.:format) posts#edit
post      GET    /posts/:id(.:format)      posts#show
          PATCH  /posts/:id(.:format)      posts#update
          PUT    /posts/:id(.:format)      posts#update
          DELETE /posts/:id(.:format)      posts#destroy

posts#indexは GETで 「/posts」にアクセスすれば良いことがわかりますね。ブラウザのURLの末尾に /posts をつけるとGETメソッドでリクエストされますから、postsコントローラのindexアクションが実行され、対応する views/posts/index.html.erb が表示されます。
「http://localhost:3000/posts」にアクセスするとみんなの投稿ページが表示され、今まで作成した3件の投稿が表示されましたか?

TOPページの設定

「http://localhost:3000/posts」というURLで投稿一覧を表示することができましたが、TOPページ「http://localhost:3000/ 」はRailsのデフォルトページのままです。
アプリらしくTOPページを作成していきましょう。
今回は今作成したposts#indexの投稿一覧ページをTOPページにしていきたいと思います。

confix/routes.rbファイルを開いて以下のように設定してください。

Rails.application.routes.draw do
  root 'posts#index'
  resources :posts
end

rootの行を追加してください。
rootの行ではTOPページを表示するコントローラとアクションを指定します。

root 'コントローラ名#アクション名'

保存しましたらルーティングを確認しましょう。

$ rails routes
Prefix    Verb   URI Pattern               Controller#Action

root      GET    /                         posts#index
posts     GET    /posts(.:format)          posts#index
          POST   /posts(.:format)          posts#create
new_post  GET    /posts/new(.:format)      posts#new
edit_post GET    /posts/:id/edit(.:format) posts#edit
post      GET    /posts/:id(.:format)      posts#show
          PATCH  /posts/:id(.:format)      posts#update
          PUT    /posts/:id(.:format)      posts#update
          DELETE /posts/:id(.:format)      posts#destroy

root の行が増えていますね。
TOPページは「/」のURLでGETリクエストと決まっています。
サーバを起動し、ブラウザでTOPページ(http://localhost:3000/)にアクセスしてみましょう。
デフォルトページではなく「みんなの投稿一覧」が表示されましたか?
これでTOPページの作成ができました。

ここでみんなの投稿一覧ページが「/」と「/posts」の二つのページで表示されるのはちょっと変ですね。そこで、/postsのページのルーティングを削除して、TOPページだけで表示させてみましょう。
config/routes.rbを以下のように編集します。

Rails.application.routes.draw do
  root 'posts#index'
  resources :posts, except: [:index]
end

exceptオプションは resourcesで自動生成される7つのルートから除外したいルートを指定するオプションとなります。
今回はposts#indexがrootと内容が被るためルートから除外しました。
ルーティングも確認してみましょう。

$ rails routes
Prefix    Verb   URI Pattern               Controller#Action

root      GET    /                         posts#index
          POST   /posts(.:format)          posts#create
new_post  GET    /posts/new(.:format)      posts#new
edit_post GET    /posts/:id/edit(.:format) posts#edit
post      GET    /posts/:id(.:format)      posts#show
          PATCH  /posts/:id(.:format)      posts#update
          PUT    /posts/:id(.:format)      posts#update
          DELETE /posts/:id(.:format)      posts#destroy

ルーティングから除外されていますね。
除外した以前のURLにもアクセスしてみましょう。「http://localhost:3000/posts」にアクセスしてみてください。

Routing Error

Routing Errorが出ました。「GET + /posts」のルーティングから除外したためにこのURLが無効になったことを意味します。
使っていないURL、不要なURLはセキュリティ上残しておくのは好ましくありませんので不要なルートは除外するようにしましょう。