\ プログラミング学習奮闘記録 /

Progate学習メモ Ruby on Rails5【〜投稿を制限する〜】

目次

バリデーション

不正なデータがデータベースに保存されないように、データをチェックする仕組みのことをバリデーションと言う

バリデーションに引っかかった場合(不正なデータの場合)にはデータベースに保存されない

バリデーションの書き方(例:空の投稿を制限する)

モデルにて「validates」を用いてカラム名と内容を指定する。

《models/post.rb》

validates :content, {presence: true} 検証する内容

   検証するカラム名

  • {presence: true}を用いることで、「そのカラムの値が存在するかどうか」をチェックすることができる

バリデーションを確認する

《ターミナル》

$ rails console

post = Post.new(content: “”)

post.save

  • 空の投稿を防ぐバリデーションを設定すると、空の投稿に対してsaveメソッドを用いて保存しようとしても、保存が失敗するようになる

文字数のバリデーション

バリデーションでは、値が存在しているかだけでなく、文字数もチェックすることができる

《models/post.rb》

validates :content,{length: {maximum: 140}}

  • 「length」を用い、{maximum: 数値}を指定することで、最大文字数を設定できる

検証する内容を複数指定する

《models/post.rb》

validates :content,{presence: true,length: {maximum: 140}}

  • コンマで区切ることで、複数指定できる

バリデーションとsaveメソッド

バリデーションに引っかかったら、もう一度入力フォームに戻るようにする。

そのためにまず、バリデーションの結果によって、 save メソッドが異なる結果になることを学ぶ

saveメソッドの戻り値

投稿をデータベースに保存するために使ってきた「saveメソッド」は、保存に成功した場合は「true」を、バリデーションに引っかかって保存に失敗した場合は「false」を戻り値として返すようになっている。

《ターミナルで確認》

$ rails console

post = Post.new(content: “”)

post.save

=> false ←保存失敗時

post.content = “我が名はアシタカ”

post.save

=> true ← 保存成功時

バリデーションの結果で表示するページを変える

新規投稿や投稿編集フォームで、投稿が失敗した時には、再びフォームを表示するようにする

save メソッドが、保存出来たら「true」、保存できなかったら「false」を返すことを利用する

表示するページを切り替える

投稿を保存できなかった場合は投稿一覧ページの代わりに投稿編集ページに転送するようにする

《posts_controller.rb》

def update

if @post.save ←保存できた場合

redirect_to(“/posts/index”)

else   ← 保存失敗した場合

redirect_to(“/post/#{@post.id}/edit”)

end

end

  • 「saveメソッド」が、保存できたかどうかで「true」または「false」を返すことを利用する
  • リスト

直前の投稿内容を表示する

直前の編集内容が消えてしまう仕組み

以上の理由から、投稿失敗時には直前の内容ではなく編集前のデータが表示されてしまう

【理由1】updateアクションでは、投稿失敗時にeditアクションに転送している

《posts_controller.rb》

def update

 redirect_to(“posts/#{@post.id/edit}”)

end

【理由2】editアクションでは、データベースから編集前のデータを取得している

《posts_controller.rb》

def edit

 @post = Post.find_by(…)

end

【理由3】フォームの初期値は、②で取得した@post.contentの内容である

《edit.html.erb》

<textarea>

<%= @post.content %>

</textarea>

直前の投稿内容を表示する仕組み

updateアクションの@postには直前の編集内容が入っているので、この@postをedit.html.erbで利用できるようにすれば、直前の編集内容を表示できるようになる。

《posts_controller.rb》

def update

@post = Post.find_by(di: params[:id])

@post.content = params[:content] ←直前の内容が入っている

end

  • editアクションを経由せずに、updateアクションからedit.html.erbを直接表示したい

renderメソッド

renderメソッドを用いることで、別のアクションを経由せずに、直接ビューを表示することができる

《posts_controller.rb》

def update

@post = Post.find_by(di: params[:id])

@post.content = params[:content] ←直前の内容が入っている

render(“posts/edit”)

end

posts/edit.html.erb》

<textarea>

<%= @post.content %>

</textarea>

  • render(“フォルダ名/ファイル名”)のように表示したいビューを指定する
  • redirect_toメソッドを使った場合と違い、そのアクション内で定義した@変数をビューでそのまま使うことができる
  • ※redirect_toはURLを指定して「redirect_to(URL)」のように書く

エラーメッセージを表示する

エラーメッセージを取得する

saveメソッドを呼び出した際にバリデーションに失敗すると、Railsでは自動的にエラーメッセージが生成されるようになっている@post.errors.full_messagesの中に、エラー内容が配列で入る

《ターミナル》

post = Post.new(content=””)

post.errors.full_messages => []

post.save => false

post.errors.full_messages => [“コメントを入力してください”]

  • リスト
  • リスト

エラーメッセージの表示

edit.html.erbのフォームの上で、each文を用いてエラー文を1つずつ表示

《edit.html.erb》

<%= @post.errors.full_messages.each do |message| %> ←エラーメッセージの配列

<%= message %>

<% end %>

サクセスメッセージを表示する

サクセスメッセージは、投稿した直後だけ表示して、それ以降は表示しないようにする

フラッシュ

ページ上に1度だけ表示されるメッセージをフラッシュという。

フラッシュが表示された後、ページを更新したり、別のページに移動したりすると、フラッシュは表示されなくなる

変数flash

アクションで変数flash[:notice]に文字列を代入すると、flash[:notice]をビューで使うことができる。

変数flashは1度表示された後に自動で削除される

《posts_controller.rb》

def update

if @post.save

flash[:notice] = “更新に成功しました”

《layous/application.erb》

<% if flash[:notice] %>

<div class=”flash”>

<% flash[:notice] %>

</div>

<% end %>

  • リスト
  • リスト

新規投稿に失敗した時に、再び新規投稿ページを表示するようにする

エラーメッセージと直前の内容を表示する方法

《posts_controller.rb》

def create

@post = Post.new(content: params[:content])

render(“posts/new”) →newアクションを経由せずにposts/new.html.rbに直接表示する

《posts/new.html.rb》

<%= @post.errors.full_messages.each do |message| %> ←エラーメッセージの配列

<%= message %> →エラーメッセージを表示

<% end %>

<textarea><%= @post.content %></textarea> →直前の投稿内容を表示する

newアクションに@postを定義する

new.html.erbで変数@postを使用するようにしますが、newアクションではまだ変数@postが定義されていない

そのため、(localhost:3000/posts/newというURL)でアクセスしたときにエラーが出てしまう。

postにPost.newを代入しておけば、うまく動く

《posts_controller.rb》

def new

@post = Post.new

end

新規投稿、削除機能のサクセスメッセージ

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

コメント

コメントする

CAPTCHA


目次