Ruby on Rails5 Progate V エラーのある投稿を防ぐ メッセージの表示
バリデーション
バリデーション・・・データベースをチェックして不正なデータが保存されないように防ぐ仕組み
モデルで設定する
validatesでカラム名と内容を指定
↓空の投稿を制限するバリデーション(presence)↓
ex.)[models/post.rb]
validates :検証するカラム名, {検証する内容}
validates :content, {presence: true}
//空の投稿を制限
↓文字数を制限するバリデーション(length)↓
ex.)[models/post.rb]
validates :content, {length: {maximum: 140}}
//文字数を140字に制限
↓複数設定する↓
検証する内容はハッシュになっているので
「 , 」で区切って複数指定できる。
ex.)[models/posts.rb]
validates :content, {presence: true , length: {maximum: 140}}
投稿に不正があれば入力フォームをまた表示する設定
seveメソッドの戻り値を利用する
= 保存成功・・・true, 保存失敗・・・false
が戻り値
ex.)[post_controller.rb]
def update
@post.find_by(id: params[:id])
@post.content = params[:content]
if @post.save
redirect_to("/posts/index") //trueだった場合 ・・・一覧に戻す
else
redirect_to("/posts/#{@oist.ud}/edit") //falseだった場合・・・編集ページに戻す
end
end
「直前の投稿内容を表示する」(いちいち最初から入力とならないように)
直前の投稿内容を初期値に設定する
投稿が消える理由・・・今回の場合、投稿に失敗するとeditアクションに転送される。
else
redirect_to("/posts/#{@oist.ud}/edit")
//edit.html.erbに転送された際に消える
editアクションはデータベースから編集前のデータを取得している。これが html.erb<textarea> の初期値になるので表示が消える。
<textarea name="content"><%= @post.content %></textarea>
updateアクションの@postには直前の入力内容がまだ入っているのでこれをhtml.erbの初期値に設定する。
@post.content = params[:content]
↓↓
renderメソッドをアクションで使う
(別のアクションを経由せず直接ビューを表示)
☆renderメソッドを使うと redirect_toメソッドを使った場合と違い、
そのアクション内で定義した@変数をビューでそのまま使うことが出来る
//renderメソッド*****************************
[post_controller.rb]
def update
@post.find_by(id: params[:id])
@post.content = params[:content]
if @post.save
redirect_to("/posts/index")
else
render("posts/edit")
// render("フォルダ名/ファイル名")
//頭の「/」はいらない
//このupdateアクション内の params[:content]を反映させたままeditアクションの処理を経由せずにeditビューを表示
end
end
「エラーメッセージの表示」
saveに失敗した時Railsに自動的に生成されるエラーメッセージを利用する
*post = Post.new(content: "")などをコンソールで試すと出てくる
html.erb のフォーム内でエラーメッセージをeach文で表示
(リロードすると勝手に消える)
[edit.html.erb]
<% @post.errors.full_messages.each do |message| %>
//errors.full_messages にエラー内容が配列で保存される
<%= message %>
<% end %>
「サクセスメッセージの表示(編集成功)」
フラッシュを利用・・・ページ上に一度だけ表示されるメッセージ
*(一度表示されたらリロード等をすると自動的に削除される)
変数 flash ・・・flashを表示する特殊変数
色々な箇所で共通で使うのでapplication.html.erbで記述する
[post_controller.rb]
def update
〜
if @post.save
flash[:notice] = "表示したい文字列"
end
end
[application.html.erb]
<%= if flash[:notice]%> //flash[:notice]が存在する時のみ実行
<div class="flash">
<%= flash[:notice]%>
</div>
<% end %>
新規投稿や削除でもメッセージを表示する
********新規投稿の成功********
def create
@post = Post.new(conent:params[:content])
if @post.save
redirect_to("/posts/index")
flash[:notice] = "投稿に成功しました"
else
render("posts/new") //投稿に失敗したら新規投稿ページに内容そのままに戻す
end
end
*****新規投稿の失敗時のエラーメッセージ表示*******
[posts_controller.rb]
def new
@post = Post.new
//newアクション経由(localhost:3000/posts/new)でアクセスした時にエラーにならない様に
end
[new.html.erb]
<% @post.errors.full_messages.each do |message| %>
<% message %>
<% end %>
<textarea name="content"><%= @post.content %></textarea>
//newアクションで@post定義がないと直前の投稿表示でエラーになる。
//renderで戻った際にエラー出る。