さらなる高みへ -higher ground -

プログラミング学習の定着を狙いとしたアウトプット(独り言)をしてみるブログ

データの保存ができるようにする

ここでは、Railsでデータを保存するための仕組みについて学習する。
少し複雑だが、Railsの中心的な機能になるため、しっかりとした理解が必要となる

  • データ保存の流れ
  • paramsについて
  • ストロングパラメータについて

データの保存の全体像の確認

Railsでのデータ保存がどのようなフローで行われるのか、先に全体の流れを押さえておく。

https://tech-master.s3.amazonaws.com/uploads/curriculums//b3e80423aaf11b9fc2ae4431d485f427.png

前の章で見ている図ですが、改めてコントローラーの役割に着目して確認する。
保存を行うために、コントローラーで行われることは大きく分けて3つある。

  1. ユーザーが入力した内容を受け取ること。paramsと呼ばれるハッシュの中にデータが格納される。
  2. 受け取ったデータに対して、セキュリティ的に問題がないかチェックする。
    これはストロングパラメータという仕組みを使って行われる。
  3. モデルに対しデータベースに保存を依頼する。この順で詳しく確認していく。

①入力内容を受け取る

ユーザーがフォームに入力した内容を保存するためには、それを受け取る仕組みが必要です。Railsではparamsというメソッドがその機能を担っていますので、詳しく見ていきましょう。

paramsとは

paramsとは、ユーザーが入力した内容などを取得することができるメソッドです。実行した結果は下記のようなハッシュ形式で返される。

{"utf8"=>"✓", "authenticity_token"=>"dJKRiq8/n0JqdQTV196odFozrjvE3Ucb9ruT3wDOUoqeBTV/4fOPF

この中には、システム的に使われる情報も含まれるので長くなっている。保存に必要なのは以下の部分である。

{"name"=>"斎藤", "image"=>"https://abc.com/pic.jpg", "text"=>"かわいい"}

このハッシュの、キーにあたる「name」「image」「text」は、フォームを作成する際のname属性で指定したものである。
必ずデータベースのカラム名と同じになるように設定する。 これは重要なポイントである。

つまり上の例だと、nameカラムに「斎藤」、imageカラムに「https://abc.com/pic.jpg」、textカラムに「かわいい」を保存できればよいということになる。

https://tech-master.s3.amazonaws.com/uploads/curriculums//aaa2bb0cee5b1a19d4da61e97bb51ebf.png

②ストロングパラメータを使って保存を許可する

ストロングパラメータは、事前に許可したデータのみ保存ができるようにして安全性を高める仕組みである。
具体的にはpermitと言うメソッドを使用します。

params.permit(:name, :image, :text)

このようにparamsに対してpermitメソッドを使用する。その時に、保存したいパラメータを引数で指定する。
カラム名の先頭に「:(コロン)」をつけてシンボルにしたものを使用する。

③モデルに対してDBへの保存を依頼する

permit済みのデータを保存するためにモデルに対して保存を依頼する。
保存するためにはcreateメソッドを使用する。

データの保存ができるようにする

ここまでの内容を踏まえて、実際にデータの保存ができるようにコードを書いていく。
保存を行うためのアクションは、7つのアクションのうち、リソースの新規登録を行いたいので「create」アクションである。

tweetsコントローラーのcreateアクションと関連するように、ルーティング、コントローラー、ビューの記述を行なっていく。

ルーティングを追加する

最初にルーティングの記述を追加する。

routes.rbを編集する

config/routes.rb

Rails.application.routes.draw do
  get   'tweets'      =>  'tweets#index' 
  get   'tweets/new'  =>  'tweets#new'   
  post  'tweets'      =>  'tweets#create'   
end

基本的に、今まで追加したのと同じ書き方をします。
ただし、今回はデータ取得ではなく投稿を行いますので、HTTPメソッドはgetではなくpostを使用します。

tweetsコントローラーを編集しよう

続いてtweetsコントローラーにコードを追加する。

app/controllers/tweets_controller.rb

class TweetsController < ApplicationController

  def index
    @tweets = Tweet.all
  end

  def new
  end

  def create
    Tweet.create(tweet_params)
  end

  private
  def tweet_params
    params.permit(:name, :image, :text)
  end

end

ここは少し複雑なので、細かく確認していく。

tweet_paramsについて

15行目でtweet_paramsというメソッドを定義している。
このメソッド内でparamsに対してpermitメソッドを使用しているので、tweet_paramsを実行すればストロングパラメータの許可ができたことになる。

また、このようなストロングパラメータ用のメソッドの名称は、「リソース名」+「_params」で「tweet_params」のようにつけるのが慣例である。

createメソッドについて

次に11行目に注目する。

ここでは、Tweet.createと記述することでtweetsテーブルにデータを保存しようとしているた、引数に「tweet_params」を指定している。
これは先に見たtweet_paramsメソッドのことである。

tweet_paramsを実行すると、先に見たような以下のハッシュが許可済みのものとして返ってくる。
この内容を元に保存を行う。

{"name"=>"斎藤", "image"=>"https://abc.com/pic.jpg", "text"=>"かわいい"}

なお、14行目のprivateはそれ以降をプライベートメソッドとして宣言するための記述です。これによってtweetsコントローラー以外のファイルから、誤ってメソッドを呼び出してしまうことを防げる。

privateの記述なかったとしてもすぐに実害が出るものではないが、オブジェクト指向では不用意なメソッドの呼び出しはできないようにしておくべきと言う考えからこのように記述する。

ビューを追加する

最後にビューを追加する。これは、保存がきちんとできたことをユーザーに伝えるためのビューになる。

create.html.erbを追加する

今までと同様に、以下の位置にファイルを追加して、名前を「create.html.erb」に変更する。

  •  app
    •  views
      •  tweets
        •  create.html.erb

続いて内容を以下の通り編集する。

app/views/tweets/create.html.erb
1
2
3
4
5
6
7
8
<div class="contents row">
  <div class="success">
    <h3>
      投稿が完了しました。
    </h3>
    <a class="btn" href="/tweets">投稿一覧へ戻る</a>
  </div>
</div>

ここまでできたら保存機能の完成である。
きちんと動くか確認してみる。

動作確認をする

最初に投稿画面を表示させる。
(アプリ名)/tweets/new にアクセスする。

Image URL欄には以下を入力する。

https://tech-master.s3.amazonaws.com/uploads/curriculums//e10f45f269ed18b785d10f30716b5cc4.png

SENDボタンをクリックした後、ビューが切り替わる。

https://tech-master.s3.amazonaws.com/uploads/curriculums//4ecbb0ce6e0a5f15049a40435cf05db2.png

さらに「投稿一覧へ戻る」をクリックしましょう。

https://tech-master.s3.amazonaws.com/uploads/curriculums//59e64c1db2fc2ba744c4709d810f28b1.png

今入力した内容が表示されればうまくいっている。

ここまででRailsでの保存機能の実装は一通り完了である。
次回からはさらに発展的な内容に取り組んでいく。

 

要点チェック