Webエンジニア目指して#39
どうもスマブラマンです。
新キャラ実装日ですね。ゼノブレ2やる前にホムラヒカリ来ちゃったな〜クリア後だったらすごいテンション上がってたと思います。
残すは2キャラ、一体何が来るんでしょう。アルルきて(切望)
さてProgateのRails Vやっていきましょう
バリデーションで空の投稿を防ぐ
データベースに保存されるデータをチェックし、意図しないものは弾くシステムのことをバリデーションという
モデルファイルに対して記述する
class Post < ApplicationRecord validates :message,{presence: true} end
第2引数の{presence: true}
が空の文字数を弾くバリデーション
第1引数のmessage
カラムに対して動作する
これを記述した状態でmessageカラムが空のレコードを保存してみると、 falseと出て失敗する(本来はtrueと出て保存内容が表示される)
actionに組み込んでやるとそのままスルーする これで空の投稿や編集ができちゃう問題は解決
バリデーションで文字数制限
validates :message,{length: {maximum:140}}
{length: {maximum:140}
の部分が文字数制限。
下のように他のバリデーションとまとめて書くことができる
validates :message,{presence: true,length: {maximum:140}}
バリデーションの結果で表示を変える
バリデーションに引っかかる状態でsaveメソッドを使ったらfalseを返すのを利用して、if文に組み込む
いつぞやの新規投稿actionを書き換える
def save @post=Post.new(message: params[:message]) if @post.save redirect_to("/post/index") else redirect_to("/post/#{@post.id}/new") end end
if文の条件でしかsaveメソッドを書いてないがちゃんと実行した上で分岐をしてくれるらしい 結果はこんな感じ
renderメソッド
render("controller名/viewファイル名")
routingアドレスを書かないように注意、viewファイルを直接参照する。接頭に/
がないのにも注意
render
はviewを再描画する
redirect
だと単純に再読み込みをするためactionの再実行によって入力した文字列が上書きされてしまうが、render
は定義や代入した変数は保持されるため、再描画直前の入力情報を表示させることが可能
以下の例のように、バリデーションで引っかかった際にrender
を使って直前の入力情報が表示されるようにする
投稿ページ(new.html.erb)
<div class="main"> <h1>新規投稿</h1> <%= form_tag("/post/save") do %> <textarea name="message"><%= @post.message %></textarea> <input type="submit" value="投稿"> <% end %> </div>
新規投稿画面だが再描画直前の入力を読み込ませるため、textareaに@post.message
を仕込んだ
saveアクション
def save @post=Post.new(message: params[:message]) if @post.save redirect_to("/post/index") else render("post/new") end end
バリデーションに引っかかりsave
がfalseを返したときにrender
で再描画をさせる
再描画時点では@post.message
は入力したレコードが代入されているため、viewで仕込んだtextareaに拾ってもらえる
newアクション
def new @post=Post.new() end
viewに@postを書いているため、saveアクションが実行されるまでは定義されていない変数があることになり、最初にnewページを開いたときにエラーが出てしまう
これを防ぐために@postに空のレコードを入れておいた
投稿エラーメッセージを表示させる
下図のように、save
がfalseを返すときにレコード.errors.full_messagesの中にエラーメッセージが配列として入力される
save
を実行するまではerrorsが空なことを利用してviewに仕込んでおく
<div class="main"> <h1>新規投稿</h1> <% @post.errors.full_messages.each do |err| %> <%= err %> <% end %> <%= form_tag("/post/save") do %> <textarea name="message"><%= @post.message %></textarea> <input type="submit" value="投稿"> <% end %> </div>
結果 なんか英語だがバリデーションの内容に対応したエラーメッセージが出ている、なんて便利なんだ
flash[:notice]
viewを一度表示したらnilにリセットされる変数。
保存に成功しました、みたいなメッセージ表示に使う
viewの上らへんにこんな感じで置いて、flash[:notice]に中身があるときだけ表示させる
<% if flash[:notice] != nil %> <div class="flash"> <%= flash[:notice] %> </div> <% end %>
saveアクションに仕込んでみた
def save @post=Post.new(message: params[:message]) if @post.save flash[:notice]="新しく投稿しました" redirect_to("/post/index") else render("post/new") end end
結果
似たようなものを削除actionや編集actionに仕込んでRails Vはおしまい!ではでは。