概要
初めて 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
の順序に注意する - モデルにバリデーションを設定すると、入力チェックができる
- エラーメッセージはカスタマイズできる