概要
初めて Ruby on Rails で Web アプリ開発するための、入門編の記事。
Rails の基礎部分をなるべく絞って解説する。
| 手順 | 記事 |
|---|---|
| #1 | Rails の開発環境構築 |
| #2 | コントローラ・ビューの基本 |
| #3 | モデルとマイグレーションの基本 |
| #4 | DB のデータを画面に表示する |
| #5 | 画面から DB にデータを登録する(今回) |
| #6 | 画面から DB のデータをの更新・削除する |
対象
- Ruby on Rails で開発をしてみたい(しなければならない状況になった)方
- HTML/CSS で簡単な Web ページを書いたことがある方
- 「DB」「SQL」という言葉の意味を何となく理解できる方
- 「REST API」や「GET」「POST」などを聞いたことがある方
- Ruby もしくは、その他のオブジェクト指向のプログラミング言語に触れた方
- 変数、四則演算、if 文、for 文、などは書いたことある
- クラス、メソッド、インスタンス、などは聞いたことある
前提
macOS で作業する前提で書いてます。Windows の方は適宜、読み替えてください🙏
- OS: macOS 13.12.1 "Ventura"
- CPU: Intel
- Ruby: v3.1.3
- SQLite3: v3.39.5
- Bundler: v2.4.9
- Rails: v7.0.4
手順(DB のデータを追加する画面を作る)
Rails でデータ登録処理を作る場合、Web アプリのデータ登録時の慣習に従って、アクションは new(フォーム入力・エラーチェック) と create(データ登録処理) の2つを使って実現する。
ルーティングを追加する
new アクションと create アクションのルーティングを追加する。
また、Top コントローラの画面をやめて、Users コントローラの index アクションをトップページに変更するため、このタイミングでルーティングの初期ページ設定も変更する。
Rails.application.routes.draw do
+ root "users#index" # アプリのトップページのアクションを指定
- get "/", to: "top#index" # 削除
get "/users", to: "users#index"
+ get "/users/new", to: "users#new" # new アクション追加
get "/users/:id", to: "users#show", as: "user"
+ post "/users", to: "users#create" # create アクション追加
end
👉 root "コントローラ名#アクション" とすることで、このアプリのトップページを指定できる。これは、get "/" よりも優先される。
👉不要となった Top コントローラ関連ファイルを削除する
- app/controllers/top_controller.rb
- app/helpers/top_helper.rb
- app/views/top/index.html.erb
- test/controllers/top_controller_test.rb
注意点 new アクションは show アクションより前に書くこと。
なぜなら、/users/:id の :id は任意の文字列が全て対象となるため、 /users/new もこれに該当してしまう。
そのため、順序を間違えると常に show アクションが先に呼ばれてしまうバグとなる。
トップページに登録ボタンを追加する
link_to に似ている button_to ヘルパーで /users/new に遷移させるボタンを追加する。
<ul>
<% @users.each do |user| %>
<li>
<%= user.name %>/<%= user.age %>
<%= link_to '詳細', user_path(user.id) %>
</li>
<% end %>
</ul>
+ <div>
+ <%= button_to "登録", { action: "new" }, method: :get %>
+ </div>
👉 button_to "ボタンラベル", {アクション}, {メソッド} と指定することで、特定のアクションのルーティングを呼び出す URL を発行できる。
ブラウザで localhost:3000 にアクセスすると以下の画面になる。

👉 ルーティングを修正したので、トップページが Users コントローラの index アクションになっている。また、登録画面がまだ無いが、ボタンを押すと /users/new にアクセスする様になっている。
登録用のアクションを追加する
コントローラに new アクションと create アクションを以下の様に追加する。
class UsersController < ApplicationController
+ def new
+ @user = User.new
+ end
+ def create
+ @user = User.new(name: params[:user][:name], age: params[:user][:age])
+
+ if @user.save
+ redirect_to @user
+ else
+ render :new, status: :unprocessable_entity
+ end
+ end
end
👉 まず new アクションが呼ばれ、画面入力された値を入れる @user を用意して画面表示。次に create アクションが呼ばれ、入力値を格納したパラメータ(params)をもとに変数を作り直し、save メソッドで DB登録を実行する。
👉 Users コントローラで redirect_to @user とすると、/users/{@user.id} の URL にリダイレクトする(通信処理のヘルパー)
👉 Users コントローラで render :new とすると、app/views/users/new.html.erb の画面を表示する(レンダリング処理のヘルパー)
データ入力フォームを作る
new アクションの画面テンプレートを作る。ここで、Rails の 「フォームビルダー(form builder)」 というヘルパーを利用する。
<h1>New User</h1>
<%= form_with model: @user do |form| %>
<div>
<%= form.label :name %><br>
<%= form.text_field :name %>
</div>
<div>
<%= form.label :age %><br>
<%= form.text_field :age %>
</div>
<div>
<%= form.submit %>
</div>
<% end %>
👉 form_with ヘルパーは、フォームをインスタンス化する(ここでは form としている)。form_with インスタンスには、「label」や「text_field」等のフォーム要素を作るメソッドが用意されている。
👉 form_with は、 HTML の <form action="/users" method="post"> に相当する。
👉 model: @user は new アクションで作ったインスタンス変数。
登録画面が完成
この時点で、トップページから「登録」ボタンで作成した登録画面に遷移できる様になっており、データも登録ができる。

手順(画面にバリデーションを追加する)
現在は、入力項目が空でもデータが登録できてしまうので、必須入力を設定するなどチェック機構を追加する。
入力内容の取得方法をシンプルにする
登録データのパラメータを生成する部分を、プライベートメソッドにまとめる。
また、パラメータ生成部分を Strong Parameters(ストロングパラメーターズ) でまとめる書き方に変更する(項目毎に何度も params[:user] と書くのを避ける)。
class ArticlesController < ApplicationController
def create
- @user = User.new(name: params[:user][:name], age: params[:user][:age])
+ @user = User.new(user_params)
if @user.save
redirect_to @user
else
render :new, status: :unprocessable_entity
end
end
+ # ここから下は アクションではなく プライベートメソッド
+ private
+ def user_params
+ params.require(:user).permit(:name, :age)
+ end
end
👉 name: params[:user][:name], age: params[:user][:age] が params.require(:user).permit(:name, :age) に置き換わる。
モデルにバリデーションを追加する
validates というバリデーションヘルパーを利用し、「名前」と「年齢」のパラメータは必須入力にする。
class User < ApplicationRecord
+ validates :name, presence: true
+ validates :age, presence: true
end
👉 presence: true で "入力必須" となる。この時点で、画面にはまだ何もエラーメッセージは表示されないが、未入力の場合に登録がストップする状態になっている(create アクションの if 文で else 側に処理分岐する)。
バリデーションエラーを画面に表示する
バリデーションは既に聞いているが、画面には明示されていないので、表示を追加する。
<h1>New User</h1>
<%= form_with model: @user do |form| %>
<div>
<%= form.label :name %><br>
<%= form.text_field :name %>
+ <% @user.errors.full_messages_for(:name).each do |message| %>
+ <div><%= message %></div>
+ <% end %>
</div>
<div>
<%= form.label :age %><br>
<%= form.text_field :age %>
+ <% @user.errors.full_messages_for(:age).each do |message| %>
+ <div><%= message %></div>
+ <% end %>
</div>
<div>
<%= form.submit %>
</div>
<% end %>
画面で確認
実際に空の状態で Submit すると、以下の様にデフォルトのエラーメッセージが表示される。

エラーメッセージを個別に変更する
表示するメッセージを個別で任意に設定したい場合は、モデルのバリデーションの部分に message を設定すると、表示内容を変更できる。
class User < ApplicationRecord
- validates :name, presence: true
+ validates :name, presence: { message: "必須入力です。" }
- validates :age, presence: true
+ validates :age, presence: { message: "必須入力です。" }
end
👉 他にも、アプリ全体の日本語化や、アプリとしてのデフォルトメッセージの定義などもできるが、今回は割愛する。
まとめ
- ルーティングに
rootを使うと、トップページ(のアクション)を指定できる - Rails での登録処理は、
newアクションとcreateアクションで実現する - ルーティング設定は、
newとshowの順序に注意する - モデルにバリデーションを設定すると、入力チェックができる
- エラーメッセージはカスタマイズできる