Railsの学習(4日目)
rails4日目
削除機能を作る
ootingはpostから始める。URLから削除したい投稿を指定できるように、「posts/:id/destroy」とする。このURLにidを含める考え方は合理的で大事だね。
postとgetの違いとは?
違いは画像の通り。destroyは投稿データを削除し、更新するのでデータベースを変更していることになり、post rootingになる
destroyアクションのリンクを作る際、今まで通りに作るとpostアクションを探してしまう。
そのため、link_toの第3引数に「{method: "post"}」を追加することで、「post」として定義されているルーティングにマッチするようになる。
destroyアクション内で行う処理は以下のとおり
投稿の制限をする
空白の投稿を制限する。
不正な投稿内容が投稿されないようにチェックする仕組みをValidation(検証、実証、認可、妥当性)という。これに引っかかるとデータベースに保存がされなくなる。
Validationは図のようにモデルとして設定する。「validates」を用いてカラム名と内容を指定します。図のように{presence: true}を用いることで、「そのカラムの値が存在するかどうか」をチェックすることができます。右の画像はvalidates(検証) :content(検証するカラム名), {presence(存在感):true}で空の投稿がないかどうか検証する、となっている。
validationの詳細な指定
validationでは値が存在しているか否かだけでなく、文字数も設定できる。
図のように「length」を用い、{maximum: 数値}を指定することで、最大文字数を設定することができます。下の画像では文字の長さ、という意味になる。
validationで検証する内容はハッシュとなっているため、図のようにコンマで区切ることで複数の内容を検証することができる。
validationに引っ掛かったらもう一度入力フォームに戻る処理を行う。これにはsaveメソッドに真偽値を用いることで、validationに引っ掛かったパターンと引っかからなかったパターンを想定することができる。
例えば保存に成功したパターンをtrue, 失敗したパターンをfalseとそれぞれ返すようにするとして、rails consoleで試すと以下のようになる。
バリデーションの結果で表示するページを変える。
例えば投稿成功なら投稿一覧のページへ、失敗なら再度投稿フォームへ、というふうに設定してみる。
投稿できなかったときは投稿編集ページに飛ぶ(リダイレクトする)ようにする。保存できたときは投稿一覧ページへ飛ぶようにする。これをif文で条件分岐することで成立させる。
直前の内容を表示したまま編集ページに戻る
そもそもなぜ投稿した内容が消えてしまうのか?それは
①updateアクションでは失敗したときにeditアクションに転送しており、編集画面にリダイレクトするようになっている。
②さらにeditアクションはデータベースから編集前のデータを取得している。
③フォームの初期値は②で取得したデータにになるよう指定されている。
そしてupdateアクションの中の「params[:content]」にはpost.contentに代入するための、直前の投稿内容が入っているため、これを編集画面で呼び出すようにすれば良い。
そこで、render(差し出す)メソッドを用いることでeditアクションを経由せず、直接編集画面に表示できるようになる。
差出先は、render("フォルダ名/ファイル名")のように表示したいビューを指定する。
renderメソッドを使うと、redirect_toメソッドを使った場合と違い、そのアクション内で定義した@変数をビューでそのまま使うことがでる。プログラムの命令がどのようなルートで実行されているか、柔軟で有機的に捉えないといけないね。
このままだとユーザーに分かりづらいので、エラ〜メッセージが出るようにする。
rails consoleで流れを見てみると、保存失敗前には@post.errors.full_messagesの中に空の配列が入っており、失敗後にのなかにエラ〜メッセージが入っているのがわかる。
それをedit.html.erbのフォームの上で、each文を用いてエラー文を1つずつ表示するようにする。
サクセスメッセージの表示
ページに一度だけ表示されるメッセージをフラッシュという。
Railsではフラッシュを表示するために、特殊な変数flashが用意されている。アクションで変数flash[:notice]に文字列を代入すると、flash[:notice]をビューで使うことができます。変数flashは1度表示された後に自動で削除されるようになっています。flashはいろいろな箇所で共通で使っていくのでapplication.html.erbで表示しましょう。
下の画像で言えば、if文があるので、もしセーブしたら、表示したい文字列をフラッシュとして表示する、という意味である。