プログラミングの勉強日記
2020年7月16日 Progate Lv.205
Ruby on RailsⅤ, Ⅵ
バリデーション
不正なデータがデータベースに保存されないようにデータをチェックするシステムをバリデーションという。バリデーションに引っかかった場合(不正なデータの場合)にはデータベースに保存されない。
バリデーションはモデルで設定する。validates
を用いてカルム名と内容を指定する。{presence: true}
を用いることでそのカラムの値が存在するかどうかをチェックできる。
class Post < ApplicationRecord
validates :content, {presence: true}
end
length
を用いて{maximum:数値}
を指定することで最大文字数を設定できる。
class Post < ApplicationRecord
validates :content, {length : {maximum:140} }
end
値の重複がないかをチェックするための{uniqueness: true}
というバリデーションもある。
class Post < ApplicationRecord
validates :content, {uniqueness: true}
end
バリデーションの内容はハッシュになっているので、コンマで区切ることで複数指定できる。
class Post < ApplicationRecord
validates :content, {presence: true, length : {maximum:140}}
end
投稿失敗画面の表示
投稿をデータベースに保存するために使っているsaveメソッド
は保存に成功した場合はtrue
をバリデーションに引っかかって保存に失敗した場合はfalse
を戻り値として返すようになっている。
投稿を保存できなかった場合は投稿一覧ページの代わりに投稿編集ページに転送する。
def update
#保存できた場合
if @post.save
redirect_to("/posts/index")
#保存できなかった場合
else
redirect_to("/posts/#{@post.id}/edit")
end
end
直前の投稿内容を表示
投稿失敗時に直前の投稿内容が消えてしまう理由
1. update
アクションでは投稿失敗時にedit
アクションに転送している。
def update
redirect_to("/posts/#{@post.id}/edit")
end
2.edit
アクションではデータベースから編集前のデータを取得している
def edit
@post=Post.find_by(...)
end
3. フォームの初期値は2で取得した@post.content
の内容である
<textarea> <%= @post.content %> </textarea>
なので、投稿失敗時には直前の内容ではなく、編集前のデータが表示されてしまう。update
アクションの@post
には直前の編集内容が入っているので、この@post
をedit.html.erb
で利用できれば、直前の編集内容を表示できる!(edit
アクションを経由せず、update
アクションからedit.html.erb
を直接表示する)
render
メソッドを用いることで、別のアクションを経由せずに直接ビューを指定する。render
メソッドを使った場合とそのアクションで定義した@変数
をビューでそのまま使える。
def update
render("posts/edit")
end
<textarea> <%= @post.content %> </textarea>
これでedit
アクションを経由せずにedit.html.erb
を直接表示できる。
エラーメッセージの取得
save
メソッドを呼び出したときにバリデーションに失敗すると、Railsでは自動的にエラーメッセージが生成される。@post.errors.full_messages
の中にエラー内容が配列で入る。
$ rails console
> post=Post.new(content:"")
> post.errors.full_message
=> []
> post.save
=> false
> post.errors.full_message
=> ["contentを入力してください"]
<% @post.errors.full_message.each do |message| %>
<%= message %>
<% end %>
@post.errors.full_message
にエラーメッセージの配列が入っているので、each文を用いることですべてが表示される。
サクセスメッセージの表示
ページ上に一度だけ表示されるメッセージをフラッシュという。フラッシュが表示された後、ページを更新したり別のページに移動したりすると、フラッシュは表示されなくなる。Railsではフラッシュを表示するために、特殊な変数flash
が用意されている。アクションで変数flash[:notice]
に文字列を入力するとflash[:notice]
でビューを使える。変数flash
は一度表示されたあとに自動で削除される。
def update
if @post.save
flash[:notice]="表示したい文字列"
...
<% if flash[:notice] %>
<div class="flash">
<%= flash[:notice] %>
</div>
<% end %>