はじめに
今回は以前の記事の続きになります。
よろしければ、以前の記事も御覧ください。
今回はバリデーションについて学んでいきましょう。
Ruby on rails を初心者向けに解説② ~リンクの作成~
Ruby on rails を初心者向けに解説③ ~データベースの作成~
Ruby on rails を初心者向けに解説④ ~命名規則とform_Tagの使い方について~
Ruby on rails を初心者向けに解説⑤ ~データベースの編集と削除~
新しいコントローラーの作成
新しいコントローラーを作成していきましょう。
今回は、投稿を管理するpostsコントローラーを作成します。ターミナルで以下のコードを実行してください。
rails g controller posts all
all.html.erbファイルで、全ての投稿を表示するようにしましょう。
そのために、新しい投稿を作成するファイルを作成します。new.html.erbファイルをpostsファイルの中に作成しましょう。
この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ファイルに、投稿を作成するコードを追加しましょう。
<%= form_tag("/posts/create") do %>
<textarea name="content" cols="30" rows="10"></textarea>
<input type="submit" value="送信">
<% end %>
/posts/create
というURLにpostリクエストを送っています。params[:content]に、textarea内部のデータが格納されて、送られます。
以下のようにルーティングしましょう。
post "posts/create" => "posts#create"
postsコントローラーのcreateアクションにルーティングされています。textareaのデータをpostsテーブルに格納するために、postsコントローラーを以下のようにコーディングします。
def create
post = Post.new(content: params[:content])
post.save
redirect_to("/posts/new")
end
これで、postsテーブルにデータを保存することができるようになりました。
以下のようにtextareaに記入して送信ボタンを押しましょう。
データベースを確認してみましょう。ターミナルで以下のコードを打ってください。
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モデルはデフォルトでは以下のようになっています。
class Post < ApplicationRecord
end
バリデーションは、以下の書式で書きます
validates :カラム名, {検証内容}
空っぽの投稿を防ぐバリデーションは以下のようになります。
class Post < ApplicationRecord
end
バリデーションは、以下の書式で書きます
validates :カラム名, {検証内容}
空っぽの投稿を防ぐバリデーションは以下のようになります。
class Post < ApplicationRecord
validates :content, {presence: true}
end
これで、空っぽの投稿を防ぐことができました。
バリデーションに引っかかった場合、saveすることができなくなります。また、saveに成功スっればTrueが戻り値として帰ってきて、saveに失敗すればFalseが戻り値として帰ってきます。
postsコントローラーを以下のように書き換えましょう。
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文字以上の投稿を防ぐバリデーションを設定してみましょう。
以下のようになります。
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ファイル内でこのインスタンス変数を表示するために、以下のように書き換えましょう。
<%= form_tag("/posts/create") do %>
<textarea name="content" cols="30" rows="10"><%= @content%></textarea>
<input type="submit" value="送信">
<% end %>
textareaの初期値に@content
を渡しています。これで、バリデーションに引っかかったときに、その値を表示することができます。
実際に試してみましょう。
以下のように20文字以上入力して、送信を押してみましょう。
特に何も変わりません。
終わりに
今回はここまでになります。
お付き合い頂きありがとうございました。
よろしければ以下の記事も御覧ください。