Ruby on Rails

MVCとルーティング

URLがどのアクションを通り、どのビューになるのかを追いかけます。

01

ルートを確認する

ルーティングはHTTPリクエストをコントローラーのアクションへ振り分けます。登録した内容は一覧コマンドで確認できます。

config/routes.rbRUBY
Rails.application.routes.draw do
  root "articles#index"
  get "/help", to: "pages#help"
  resources :articles
end
確認COMMAND
bin/rails routes
一部の表示例OUTPUT
root GET    /                    articles#index
      GET    /help                pages#help
articles GET /articles(.:format) articles#index
article  GET /articles/:id       articles#show

resources :articlesは一覧、詳細、新規作成、編集、更新、削除に対応するルートをまとめて作ります。URL、HTTPメソッド、アクションの組み合わせを意識してください。

02

コントローラーとビュー

コントローラーのインスタンス変数は、対応するビューから参照できます。

controllerRUBY
class ArticlesController < ApplicationController
  def index
    @articles = Article.order(created_at: :desc)
  end

  def show
    @article = Article.find(params[:id])
  end
end
index.html.erbERB
<h1>記事一覧</h1>
<ul>
  <% @articles.each do |article| %>
    <li><%= link_to article.title, article %></li>
  <% end %>
</ul>

<%= ... %>は値をHTMLへ出力し、<% ... %>は処理だけを実行します。ループの中でも表示する部分に出力タグを使うかを確認しましょう。

03

パスパラメーター

/articles/:id:idparams[:id]で取得できます。存在しないIDを指定した場合はActiveRecord::RecordNotFoundになるため、必要なら404画面へ対応します。

詳細画面RUBY / ERB
# controller
def show
  @article = Article.find(params[:id])
end

# show.html.erb
<h1><%= @article.title %></h1>
<p><%= simple_format(@article.body) %></p>
<%= link_to "一覧へ戻る", articles_path %>
表示結果BROWSER
最初の記事
Railsを学んでいます
一覧へ戻る
04

更新・削除のルート

resourcesは一覧と詳細だけでなく、新規作成、編集、更新、削除のルートも作ります。更新はPATCH、削除はDELETEというHTTPメソッドで意図を表します。

config/routes.rbRUBY
resources :articles, only: [:index, :show, :edit, :update, :destroy]
ルートの確認OUTPUT
GET    /articles/:id/edit  articles#edit
PATCH  /articles/:id       articles#update
DELETE /articles/:id       articles#destroy
controllerRUBY
def update
  @article = Article.find(params[:id])
  if @article.update(article_params)
    redirect_to @article, notice: "更新しました"
  else
    render :edit, status: :unprocessable_entity
  end
end

def destroy
  Article.find(params[:id]).destroy!
  redirect_to articles_path, status: :see_other
end
ビューERB
<%= link_to "編集", edit_article_path(@article) %>
<%= button_to "削除", @article, method: :delete,
      data: { turbo_confirm: "削除しますか?" } %>

削除は取り消せない操作なので、確認ダイアログや権限確認を追加します。Turboを使わない構成では、フォームがDELETEメソッドを送信できる仕組みも確認してください。

05

名前空間とネスト

管理画面を通常画面と分けるときはnamespace、親子関係をURLへ表すときはネストしたresourcesを使います。

config/routes.rbRUBY
namespace :admin do
  resources :articles
end

resources :articles do
  resources :comments, only: [:index, :create]
end
生成されるパスOUTPUT
GET /admin/articles       admin/articles#index
GET /articles/:article_id/comments comments#index
POST /articles/:article_id/comments comments#create

ネストは親子関係が明確な範囲に絞ります。深くネストしすぎるとURLとヘルパーが読みにくくなるため、関連が必要な操作だけを選びます。

PRACTICE

練習問題

問題:/aboutを追加する

PagesController#aboutを作り、/aboutで「このアプリは記事を管理します」と表示してください。

解答例RUBY
get "/about", to: "pages#about"

def about
  @message = "このアプリは記事を管理します"
end

<p><%= @message %></p>