Ruby on rails を初心者向けに解説⑥　~バリデーションの作成~

#はじめに
今回は以前の記事の続きになります。

よろしければ、以前の記事も御覧ください。

今回はバリデーションについて学んでいきましょう。

[Ruby on rails を初心者向けに解説①](https://qiita.com/renesisu727/items/c81e29c619dbd4b5ea76)

[Ruby on rails を初心者向けに解説②　~リンクの作成~](https://qiita.com/renesisu727/items/d729616473981e763fdd)

[Ruby on rails を初心者向けに解説③　~データベースの作成~](https://qiita.com/renesisu727/items/c647582a59cfd7bf0a98)

[Ruby on rails を初心者向けに解説④ ~命名規則とform_Tagの使い方について~](https://qiita.com/renesisu727/items/f0f3de5377358f8768ed)

[Ruby on rails を初心者向けに解説⑤ ~データベースの編集と削除~](https://qiita.com/renesisu727/items/8f3a4b7c52c888b52be1)

#新しいコントローラーの作成
新しいコントローラーを作成していきましょう。

今回は、投稿を管理するpostsコントローラーを作成します。ターミナルで以下のコードを実行してください。

```
rails g controller posts all
```

all.html.erbファイルで、全ての投稿を表示するようにしましょう。

そのために、新しい投稿を作成するファイルを作成します。new.html.erbファイルをpostsファイルの中に作成しましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411258/7b03f4fd-a0fd-63f5-9a61-31957d5fddca.png)

このnew.html.erbファイルで、新しい投稿を作成していきます。

#新しいモデルの作成
では、投稿を管理するデータベースを作成しましょう。今回は、まだデータベースを全く作成していないので、モデルから作成していきます。

モデルとは、`データベースの情報を操作する仕組み`であり、`データベースとのやり取りを行うクラス`とも言うことができるものでしたね。

モデルは通常、小文字から始まる単数形で命名します。なぜなら、モデルとはtableに対して一つしか存在しないからです。

```
 rails g model post content: string
```

このようにモデルを作成すると、同時にデータベースの設計図であるmigrationファイルが作成されるのでしたね。

以下のコードでマイグレーションファイルを実行しましょう。

```
rails db:migrate
```

データベースコンソールから、作成したtableを確認してみましょう。

```
rails dbconsole
.table
```

>ar_internal_metadata  schema_migrations   
posts                 users

postsテーブルが作成されていますね。以下のコードで中身を見てみましょう。

```
.schema posts
```

>CREATE TABLE IF NOT EXISTS "posts" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "content" varchar, "string" varchar, "created_at" datetime NOT NULL, "updated_at" datetime NOT NULL);


#投稿を作成
new.html.erbファイルに、投稿を作成するコードを追加しましょう。

```new.html.erb
<%= form_tag("/posts/create") do  %>  
  <textarea name="content" cols="30" rows="10"></textarea>
  <input type="submit" value="送信">
<% end %>
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411258/29bb81bb-c092-6524-3bac-849f0eb21765.png)

`/posts/create`というURLにpostリクエストを送っています。params[:content]に、textarea内部のデータが格納されて、送られます。

以下のようにルーティングしましょう。

```routes.rb
post "posts/create" => "posts#create"
```

postsコントローラーのcreateアクションにルーティングされています。textareaのデータをpostsテーブルに格納するために、postsコントローラーを以下のようにコーディングします。

```posts_controller.rb
def create
  post = Post.new(content: params[:content])
  post.save
  redirect_to("/posts/new")
end
```

これで、postsテーブルにデータを保存することができるようになりました。

以下のようにtextareaに記入して送信ボタンを押しましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411258/4d5efbc4-660b-b397-659e-5cd0135edd16.png)

データベースを確認してみましょう。ターミナルで以下のコードを打ってください。

```
rails dbconsole
.header on
select * from posts;
```

>id|content|string|created_at|updated_at
1|pocomaru||2020-05-23 10:37:51.509719|2020-05-23 10:37:51.509719

このように、投稿をデータベースに格納することができました。

##バリデーションの設定
バリデーションとは、データベースにデータを保存する際にかける制約のことです。

例えば、何かのサイトにログインする際にメールアドレスやパスワードが空っぽでもログイン可能だとやばいですよね。

そんなことを防ぐために存在します。

バリデーションは、モデルに設定します。

実際に設定してみましょう。

###空っぽの投稿を防ぐ
空っぽの投稿を防ぐバリデーションを考えます。

投稿を保存するのはpostsテーブルなので、このバリデーションはpostモデルのPostクラス内部に記入します。

postモデルはデフォルトでは以下のようになっています。

```post.rb
class Post < ApplicationRecord
end
```


バリデーションは、以下の書式で書きます

`validates :カラム名, {検証内容}`

空っぽの投稿を防ぐバリデーションは以下のようになります。

```post.rb
class Post < ApplicationRecord
end
```


バリデーションは、以下の書式で書きます

`validates :カラム名, {検証内容}`

空っぽの投稿を防ぐバリデーションは以下のようになります。

```post.rb
class Post < ApplicationRecord
    validates :content, {presence: true}
end
```

これで、空っぽの投稿を防ぐことができました。

バリデーションに引っかかった場合、saveすることができなくなります。また、saveに成功スっればTrueが戻り値として帰ってきて、saveに失敗すればFalseが戻り値として帰ってきます。

postsコントローラーを以下のように書き換えましょう。

```posts_controller.rb
def create
  post = Post.new(content: params[:content])
  if post.save
    redirect_to("/posts/all")
  else
    redirect_to("/posts/new")
  end
```

このようにコードを書き換えることで、saveが成功した場合には`/posts/all`にリダイレクトし、saveが失敗した場合には`/posts/new`にリダイレクトします。

これで、空っぽの投稿を排除するバリデーションを作成することができました。

次は、一定以上の文字数を削除するバリデーションを作成してみましょう。

###一定以上の文字数を防ぐ
今回は20文字以上の投稿を防ぐバリデーションを設定してみましょう。

以下のようになります。

```post.rb
class Post < ApplicationRecord
    validates :content, {presence: true}
    validates :content, {length: {maximum: 20}}
end
```

この`validates :content, {length: {maximum: 20}}`の部分により、20文字以上の投稿を制限することができるようになりました。

しかし、このようにバリデーションを設定するだけだと、問題があります。20文字以上の投稿をしたときに、textareaが空っぽになってしまうのです。

理由はpostsコントローラーにあります。バリデーションに引っかかり、`redirect_to("/posts/new")`が呼ばれたとき、ルーティングによりpostsコントローラーのnewアクションが実行されます。そうすると、インスタンス変数をnew.html.erbファイルに送ることができないため、頑張って書いたtextareaが空っぽになってしまうのです。

これを防ぐために、`render`というメソッドを使います。

renderとはレンダリングすることができるメソッドであり、レンダリングとはブラウザにviewファイルを読み込ませて描画させることです。

renderメソッドをviewファイル内で使うと、複数のviewファイルの共通の部分を描画する部分テンプレートを使うことができます。

今回はコントローラー内部で使うことにより、アクションを介することなくレンダリングを行うことで、作成したインスタンス変数をviewファイルに渡すことができます。

postsコントローラーを次のように書き換えましょう。

```
def create
  post = Post.new(content: params[:content])
  @content = params[:content]
  if post.save
    redirect_to("/posts/all")
  else
    render("posts/new")
  end
end
```

`@content`に、投稿の内容を格納した後、redirect_to の代わりにrenderを使ってnew.html.erbファイルを描画しています。

このようにすることで、インスタンス変数であ`@content`をnew.html.erbに渡すことができます。

new.html.erbファイル内でこのインスタンス変数を表示するために、以下のように書き換えましょう。

```new.html.erb
<%= form_tag("/posts/create") do  %>  
  <textarea name="content" cols="30" rows="10"><%= @content%></textarea>
  <input type="submit" value="送信">
<% end %>
```

textareaの初期値に`@content`を渡しています。これで、バリデーションに引っかかったときに、その値を表示することができます。

実際に試してみましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411258/1ea53456-c2b1-96a6-b8d3-9c2ac521f3e1.png)

以下のように20文字以上入力して、送信を押してみましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411258/5225c835-eed8-6dde-4d3c-8e460d94a1b6.png)

特に何も変わりません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411258/22f80315-cff2-5a28-4877-e09badb5ab99.png)

#終わりに
今回はここまでになります。

お付き合い頂きありがとうございました。

よろしければ以下の記事も御覧ください。


[Ruby on rails を初心者向けに解説⑦　~フラッシュの実装~](https://qiita.com/drafts/fd36234d669283c87048/edit)