2
1

More than 3 years have passed since last update.

投稿の制限(Ruby on Rails)

Last updated at Posted at 2020-07-15

プログラミングの勉強日記

2020年7月16日 Progate Lv.205
Ruby on RailsⅤ, Ⅵ

バリデーション

 不正なデータがデータベースに保存されないようにデータをチェックするシステムをバリデーションという。バリデーションに引っかかった場合(不正なデータの場合)にはデータベースに保存されない。
 バリデーションはモデルで設定する。validatesを用いてカルム名と内容を指定する。{presence: true}を用いることでそのカラムの値が存在するかどうかをチェックできる。

models/posts.rb
class Post < ApplicationRecord
  validates :content, {presence: true}
end

 lengthを用いて{maximum:数値}を指定することで最大文字数を設定できる。

models/posts.rb
class Post < ApplicationRecord
  validates :content, {length : {maximum:140} }
end

 値の重複がないかをチェックするための{uniqueness: true}というバリデーションもある。

models/posts.rb
class Post < ApplicationRecord
  validates :content, {uniqueness: true}
end

 バリデーションの内容はハッシュになっているので、コンマで区切ることで複数指定できる。

models/posts.rb
class Post < ApplicationRecord
  validates :content, {presence: true, length : {maximum:140}}
end

投稿失敗画面の表示

 投稿をデータベースに保存するために使っているsaveメソッドは保存に成功した場合はtrueをバリデーションに引っかかって保存に失敗した場合はfalseを戻り値として返すようになっている。
 投稿を保存できなかった場合は投稿一覧ページの代わりに投稿編集ページに転送する。

posts_controller.rb
def update
  #保存できた場合
  if @post.save
    redirect_to("/posts/index")
  #保存できなかった場合
  else
    redirect_to("/posts/#{@post.id}/edit")
  end
end

直前の投稿内容を表示

 投稿失敗時に直前の投稿内容が消えてしまう理由

 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. フォームの初期値は2で取得した@post.contentの内容である

edit.html.erb
<textarea> <%= @post.content %> </textarea>

なので、投稿失敗時には直前の内容ではなく、編集前のデータが表示されてしまう。updateアクションの@postには直前の編集内容が入っているので、この@postedit.html.erbで利用できれば、直前の編集内容を表示できる!(editアクションを経由せず、updateアクションからedit.html.erbを直接表示する)
 renderメソッドを用いることで、別のアクションを経由せずに直接ビューを指定する。renderメソッドを使った場合とそのアクションで定義した@変数をビューでそのまま使える。

posts_controller.rb
def update
  render("posts/edit")
end
posts/edit.html.erb
<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を入力してください"]
posts/edit.html.erb
<% @post.errors.full_message.each do |message| %>
  <%= message %>
<% end %>

 @post.errors.full_messageにエラーメッセージの配列が入っているので、each文を用いることですべてが表示される。

サクセスメッセージの表示

 ページ上に一度だけ表示されるメッセージをフラッシュという。フラッシュが表示された後、ページを更新したり別のページに移動したりすると、フラッシュは表示されなくなる。Railsではフラッシュを表示するために、特殊な変数flashが用意されている。アクションで変数flash[:notice]に文字列を入力するとflash[:notice]でビューを使える。変数flashは一度表示されたあとに自動で削除される。

posts_controller.rb
def update
  if @post.save
    flash[:notice]="表示したい文字列"
  ...
layouts/application.html.erb
<% if flash[:notice] %>
  <div class="flash">
    <%= flash[:notice] %>
  </div>
<% end %>
2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1