はじめに
Rails チュートリアルなどで、Railsの勉強をしていてフォームを作成して、データをフォームから入力して、最終的にDBに格納するという、View
、Controller
、DB
のデータの流れが勉強になったので、まとめておきます。
環境
この記事では以下の環境(2018年6月26日時点)で動作確認できました。
- Ruby: 2.4.1
- Rails: 5.0.7
モデル
モデルの構成などは以前に作成した記事に詳しく記載しましたので、ここでは割愛します。
ルーティング
ルーティングの設定は以下の通りです。
$ rails routes
Prefix Verb URI Pattern Controller#Action
root GET / toppages#index
signup GET /signup(.:format) users#new
users POST /users(.:format) users#create
new_user GET /users/new(.:format) users#new
user GET /users/:id(.:format) users#show
データの流れを大まかに
Webアプリケーションでよく見るユーザー登録に関する、View
、Controller
、DB
のデータの流れを説明していきます。大まかには、
-
- ユーザーが登録画面へ遷移するリンクをクリック(URLは
~/signup
とする)
- ユーザーが登録画面へ遷移するリンクをクリック(URLは
-
- ルーティング |
Get
(HTTPリクエスト) | URLからアクセスすべきcontroller
とアクション
を判別(users#new
)
- ルーティング |
-
- コントローラが呼び出されてその中のアクションの処理が走って必要なデータ(があれば)(今回はインスタンス変数(
@user
))それをView
に送る
- コントローラが呼び出されてその中のアクションの処理が走って必要なデータ(があれば)(今回はインスタンス変数(
-
- ビュー | インスタンス変数の内容を元にHTMLを作成、表示
-
- ユーザーがフォームを入力し、ユーザー登録ボタンを押した
-
- ルーティング |
Post
(HTTPリクエスト)なので | URLからアクセスすべきcontroller
とアクション
を判別(users#create
しかない)
- ルーティング |
-
- コントローラが呼び出されてその中のアクションの処理が走って必要なデータ(インスタンス変数
@user
)をDBに保存
- コントローラが呼び出されてその中のアクションの処理が走って必要なデータ(インスタンス変数
-
- DBに保存された
それぞれを説明していきます。
ユーザーが登録画面へ遷移するリンクをクリック
例えばユーザーが新規登録ボタンをクリックしたら、URLが~/sigup
だったら
ルーティングからコントローラ(users
)のアクション(new
)を判別
URLが~/sigup
だったら、どこのコントローラに行けばいいかルーティング確認したら、users
コントローラのnew
アクションと判別
コントローラ(users
)のアクション(new
)内の処理
def new
@user = User.new
end
User
という名のモデルクラスに、new
というメソッドを使って、新規レコードのためのモデルインスタンスを作成します。
今回は、何もデータがないので、空のインスタンスをここで作成して、インスタンス変数(@user
)に代入します。
インスタンス変数を、フォームがあるView
に送ります。
ここでは進むビューの指示がありません。なので、デフォルトの views/users/new.html.erb
へ処理が進みます。
HTMLを作成し、ブラウザに表示
見た目はBootstrapベースなので、こんな感じ。
この一個一個のフォームに、users
コントローラのnew
アクションで作った空のインスタンスに、実際のデータをユーザーに入れてもらって、のちにDBに格納していきます。
ユーザーがフォームを入力し、ユーザー登録ボタンを押した
全部入力して、登録するボタンをおしたら、form内の情報をまとめてサーバへ送信(Post
リクエストを送信)します。
デベロッパーツールを確認して見ましょう。その中のネットワークを見てみましょう。HTTPのヘッダーの中の情報を見ると(右側)、HTTPメソッドがPOSTであることがわかるかと思います。
パラメータをクリックすると、フォームから送られて来たデータを確認することができます。
次は、飛んだこのリクエストがどのように処理されるかを見ていきます。
ルーティングからコントローラ(users
)のアクション(create
)を判別
URLが~/sigup
だったら、どこのコントローラに行けばいいかルーティング確認したら、users
コントローラのnew
アクションと判別
users
からのPost
メソッドなので、デフォルトではusers
コントローラのcreate
アクションへ処理が渡ると思います。
コントローラ(users
)のアクション内の処理
def create
# ストロングパラメータから精査されたデータだけをインスタンスに格納
@user = User.new(user_params)
# インスタンスの保存に成功した場合の処理
if @user.save
flash[:success] = "ユーザを登録しました"
redirect_to @user
# インスタンスの保存に失敗した場合の処理
else
flash[:danger] = "ユーザの登録に失敗しました"
render :new
end
end
private
def user_params
params.require(:user).permit(:name, :email, :password, :password_confirmation)
end
コード下部にある private
は、それ以降に定義されたメソッドがアクションではなく、このクラス内でのみ使用するメソッドであると明示しています。
なので、def user_params
は、アクションではなく単なるメソッドとなります。また、このメソッドはStrong Paramter
です。これは必要なパラメータを把握して、送信されきたデータをフィルタリングすることができます。
今回は、
-
params.require(:user)
でUser
モデルのフォームから得られるデータに関するものだと明示 -
permit
以降がフィルタリングさせずに通すカラムを指定しています。
DB保存
mysql> select * from users;
+----+----------+--------------------+--------------------------------------------------------------+---------------------+---------------------+
| id | name | email | password_digest | created_at | updated_at |
+----+----------+--------------------+--------------------------------------------------------------+---------------------+---------------------+
| 7 | pass7777 | pass7777@gmail.com | $2a$10$Hofz4hjxvF4sors86Q1kZugn/FGdAB/7SE.4/ZTuyfi4aJrItV.Am | 2018-06-25 08:26:05 | 2018-06-25 08:26:05 |
+----+----------+--------------------+--------------------------------------------------------------+---------------------+---------------------+
7 rows in set (0.00 sec)
格納されたことを確認しました(idの1から6を省略しています)。
以上です!
この記事を読んだ方に
この記事を読んで、誤っている箇所をみつけたり、追記した方がいい内容などありましたら、編集リクエストやコメント欄で指摘していただけると助かります。