【初心者用】Ruby on Railsの勉強【投稿機能の実装】

ここではアプリケーションにおける投稿機能の実装について教えていきます。

 

あくまで初心者向けの記事ですので該当しない方は別の記事を見ることをお勧めします。初心者の方ができるだけわかりやすいように噛み砕いて解説していきます。それではいきましょう。

 

今回、実装していくのはツイートの投稿機能です。前回は【投稿一覧表示】のアプリを作成しました。まだ、そちらを作ってないよって方はこちらからまず、一覧表示をさせてみましょう。>>Ruby on Railsの勉強【一覧表示機能の実装】

 

今回もモデル名、コントローラー名はhogeまたはhogesを使用していますので自分で作成しているアプリケーションように随時変更しましょう。

 

 

✔︎本記事の内容

  • CRUDのC(create)を覚える
  • newアクションとcreateアクションを実装する
  • 画面を新設の流れを覚える(投稿完了画面の実装)
  • バリデーションを理解する

 

投稿機能を実装してみよう

投稿機能を実装するためにはindexアクションのnewとcreateを使用します。もしも、indexアクションがわからないよって方は別記事にて解説していますのでご覧になってください。(CRUDについても解説しています。)

【初心者用】Ruby on Railsの勉強【CRUDとindexアクション】

 

新しい投稿するための仕組みは以下の通りです。

ツイート投稿の仕組み

 

 

今から赤い枠線部分のツイート投稿ページへのアクセスするための処理をRailsで設定していきます。

投稿ページへのアクセスにはnewアクションを使用します。それではやってみましょう。

 

✔︎newアクションのルーティングをしよう

config/routes.rb
1
2
3
4
5
Rails.application.routes.draw do
  # For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html
  root to: 'hoges#index'
  resources :hope, only: [:index, :new]
end

 

routes.rbを以下のように編集しましょう。resourcesに:newを追加したことによってnewアクションを使用することができます。これによりhttp://localhost:3000/hoges/newにアクセスされた場合は、hogesコントローラーのnewアクションが実行される設定ができました。

 

✔︎newアクションをコントローラーに定義しよう

indexアクションの時と同様にコントローラーを編集してnewアクションの処理が行われるようにします。以下のように編集してみましょう。

app/controllers/hoges_controller.rb
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
class TweetsController < ApplicationController

  def index
    @hoges = Hoges.all
  end

  def new
    @hoge = Hoge.new
  end

end

 

@hogesというインスタンス変数にHoge.newを代入します。Active Recordメソッドのnewは新しいデータの生成するときに使用します。@hogesというインスタンス変数を定義する目的は投稿画面のビューを作成する際に使用するからです。

 

✔︎投稿画面のビューを作成しよう

投稿画面を作るためにform_withというヘルパーメソッドを使います。ヘルパーメソッドとは簡単にいうとビューを作成する際に見栄えを手助けしてくれるメソッドです。他にも色々あるみたいですが、僕も全ては把握していません。form_withは投稿フォームを作るときに使うメソッドになります。

 

✔︎modelオプションを使おう

【例】PicTweet以降のform_with
1
2
3
<%= form_with(model: @hoge, local: true) do |form| %>
  <%# フォームの内部 %>
<% end %>

 

上記のようにmodelオプションで@hogesを指定すると先ほどコントローラーで定義したnewアクションの処理を代入することができます。イメージとしてはこんな感じです。

 

form_withでインスタンスを利用する

このようにmodelオプションでインスタンスを指定することでリンク先urlを記述する必要がなくなります。かなり使われる方法ですのでぜひ、覚えておきましょう。

 

✔︎new.html.erbを編集してみよう

newアクションのビューファイルを作成します。コピペOKです。

app/views/hoges/new.html.erb
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
<div class="contents row">
  <div class="container">
    <h3>投稿する</h3>
    <%= form_with(model: @hoge, local: true) do |form| %>
      <%= form.text_field :name, placeholder: "Nickname" %>
      <%= form.text_field :image, placeholder: "Image Url" %>
      <%= form.text_area :text, placeholder: "text", rows: "10" %>
      <%= form.submit "SEND" %>
    <% end %>
  </div>
</div>

 

4行目で指定している@hogeという変数はHoges.newという処理を行うという意味です。この方法を用いると投稿先のパスやHTTPメソッドを指定する必要がなくなるので記述を簡略化することができます。出来上がった投稿フォームを見てみましょう。

 

 

これで投稿するためのフォームが完成しました。次に行うことは投稿したデータが保存される仕組みを作ることです。データを保存しないとユーザーが新規投稿を見ることができません。

 

ツイートの保存処理の実装

簡単に説明するとテーブルに投稿したデータを保存する仕組みを作っていきます。図の右部分を作っていきます。

ツイート保存の仕組み

 

✔︎createアクションのルーティングをしよう

大体慣れてきたと思います。新しいアクションを使用する際はまず、ルーティングを行います。以下のように編集します。

config/routes.rb
1
2
3
4
5
Rails.application.routes.draw do
  # For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html
  root to: 'hoges#index'
  resources :hoges, only: [:index, :new, :create]
end

 

これでcreateアクションへのルーティングができました。次にコントローラーで処理を定義しましょう。

 

✔︎ストロングパラメーターについて知っておこう

ストロングパラメーターとは、指定したキーを持つパラメーターのみを受け取るように制限するものです。ストロングパラメーターを使用する理由は、受け取るパラメーターを制限しなければ、仕様以外のパラメーターも使われてしまうためです。この状態だと、意図しないデータの更新をされる可能性が発生します。

 

たとえば、他人のログインパスワードを変更するパラメーターを追加で送信すれば、勝手にパスワードを変更できてしまうのです。これを回避するために、ストロングパラメーターを使用し、パラメーターを制限する必要があります。

 

簡単に言うと数字しか送れないようにしたり、画像しか送れないようにする方法ですね。Twitterでは文字数が144文字に制限されていたりとかしますよね。制限をかける方法がストロングパラメータということです。

 

ストロングパラメーターの定義には、requireメソッドと、permitメソッドを組み合わせて使用します。

 

 

✔︎requireメソッドについて学ぼう

requireメソッドは送信されたパラメーターの情報を持つparams(データベースの箱みたいなもの)が、使用できるメソッドです。requireメソッドは、パラメーターからどの情報を取得するか、選択できるものです。

requireメソッドの使い方についてみていきましょう。

【例】paramsの中身とrequire
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
params  #=> 中身は以下の内容
{
  "utf8" => "✓",
  "authenticity_token" => "token",
  "モデルA" => {
    "image" => "image.jpg",
    "text" => "sample text"
  },
  "commit" => "SEND",
  "controller" => "hoges",
  "action" => "create"
}

params.require(:モデルA)
#=> { "image" => "image.jpg", "text" => "sample text" }

params[:モデルA]  # 結果は同じだが、もしモデルAが存在しない場合はエラーになってくれない
#=> { "image" => "image.jpg", "text" => "sample text" }

params.require(:commit)  # モデル名以外のキーも指定できる
#=> "SEND"

 

paramsの中身は適当です。モデルAという変数の中にはimageとsample textというパラメーターが入っています。なので数ある情報のうちimageとsample textのみを取得できるようにしています。

paramsの記述方法は上記のように複数ありますがparams.require(:モデル名)とする方が推奨されています。理由は上述していますがエラーが生じてくれないからです。うまくアプリが作動していないのにエラー箇所がわからないという事態を避けるために1番目の記述を使用しましょう。

 

このようにrequireメソッドでは色んな種類のパラメータ(データ)を取得することができます。続いてpermitメソッドというものを使って取得できるパラメータを制限していきます。

 

✔︎permitメソッドについて学ぼう

使い方はrequireメソッドとあまり変わりません。permitメソッドで取得したいキーを選択します。上記のようなrequireメソッドを定義したとします。その後にpermitメソッドを定義するとpermitメソッドで指定されたキーしか所得できないように制限をかけるのです。

 

例えばrequireメソッドで個人情報で氏名、電話番号、メールアドレスという情報を受け取るように設定したとします。次に氏名を登録するフォームでは氏名以外のデータを受け付けないようにする。電話番号フォームでは電話番号以外を受け付けないようにする。これがpermitメソッドの役割です。

 

記述の仕方は以下の通り

【例】permit
1
params.require(:モデル名).permit(:キー名, :キー名) # 取得したいキーを指定する

 

【例】permitでキーを制限
1
2
3
4
5
6
7
8
params.require(:post)
#=> { "image" => "image.jpg", "text" => "sample text" }

params.require(:post).permit(:image)  # imageのみを指定(textは取得されない)
#=> { "image" => "image.jpg" }

params.require(:post).permit(:image, :text)  # 指定したパラメーターだけの取得を約束する
#=> { "image" => "image.jpg", "text" => "sample text" }

 

上記だと4行目ではimageのみを取得できるようにしています。7行目ではimageとtextを取得できるようにしています。

なんとなくわかりましたか?今度はストロングパラメーターを実際にメソッドとして記述していきます。その際はプライベートメソッドというものに定義していきます。

 

✔︎プライベートメソッドを使ってみよう

プライベートメソッドはクラス外から呼び出すことの出来ないメソッドです。なぜ、プライベートメソッドを使用するのかというとメソッドの中には呼び出されるとエラーが生じるものがあります。そんなときにプライベートメソッドに記述しておくことでクラス外から誤って呼び出される心配がなくなります。

 

✔︎createアクションのcontrollerを編集してみよう

app/controllers/hoges_controller.rb
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
class TweetsController < ApplicationController

  def index
    @hoges = Hoges.all
  end

  def new
    @hoge = Hoge.new
  end

  def create
    Hoge.create(hoge_params)
  end

  private
  def hoge_params
    params.require(:hope).permit(:name, :image, :text)
  end

end

 

createアクションにHoges.create(hoget_params)と記述し新規投稿した際にhogesというデータベースにデータを保存する仕組みを作っています。そして、プライベートメソッドで投稿したhogeというデータのうちnameとimage、textのみを取得するように制限をかけています。

 

 

✔︎投稿完了画面ビューを作ろう

indexアクションの時と同様にcreateアクションに対してレスポンスとして返す見た目(ビュー)を作成します。

app→views→hogesのディレクトリにcreate.html.erbというファイルを作りましょう。以下のように編集します。

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

 

 

バリデーションの設定

バリデーションとはデータを保存、登録する際に一定の制限をかけることを言います。例えば、空のデータを送れないようにする。すでに登録済みのデータを重複できないようにする。文字数に制限をかけるなどです。

 

バリデーションを作成する際はモデルにvalidatesメソッドを記述します。

 

✔︎validatesを記述しよう

バリデーションの書き方は以下の通りです。

【例】モデルファイル
1
validates :カラム名, バリデーションの種類

 

下記の例を見てみましょう。

【例】モデルファイル
1
validates :name, presence: true

 

presence: trueという記述は「nameカラムが空ではないか」という意味になります。このバリデーションを作成することで名前が空欄の場合、データを保存することができなくなります。よく見かける「必須事項に記入がありません」みたいなものですね。

 

✔︎tweet.rbを編集してみよう

app/models/hoge.rb
1
2
3
class Hoge < ApplicationRecord
  validates :text, presence: true
end

 

これによってからのツイートは投稿できないようになりました。バリデーションについて理解が深まったかと思います。

 

実際にアプリケーションを実装する上でセキュリティというのは欠かせないものですよね。個人情報や顧客情報を守るために登録処理にストロングパラメータやバリデーションを用いるわけです。

 

今回の記事はここまでになります。最後まで読んでいただきありがとうございます。ツイート機能の実装についての記事は更新していきますので是非ご覧になってアプリケーションを作れるようになりましょう。

Follow me!

コメントを残す

メールアドレスが公開されることはありません。