Day10です!
今日もがんばっていきましょー!
読んでいただいている方、いつもありがとうございます!
初心者なもので、たまに間違った内容もあるかと思います。
その際にはコメントやTwitterでご指摘いただけると幸いです!
[Day10]第十章10.1〜10.1.4作業ログ
第十章はユーザーの更新、表示、削除の実装
第十章はユーザーの更新、表示、削除の実装です。
具体的には、以下の4つのアクションの実装。
- edit
- update
- index
- destroy
まずは自分のユーザー情報を編集できるようにする。
次に、すべてのユーザーを表示するページの作成。
あとは、認可したユーザーに限り、ユーザーの削除ができるようにする。
こんな流れでやっていきます。
編集ページの作成
editアクションで、現在のログインユーザーを所得してあげる。
URLが”/users/5/edit”みたいにユーザーIDが含まれているので、params[:id]でとってこれる。
class UsersController < ApplicationController
...
def edit
@user = User.find(params[:id])
end
...
end
次ははビューファイルedit.html.erbの作成。
edit.html.erbはnew.html.erbと中身がほとんど同じ。
演習でパーシャル機能を使って、共通部分を省略できるようにしました。
実際のコードは演習のところ参照。
入力フィールドの送信先は自動判別されている
edit.html.erbはnew.html.erbのもともとのコード(リスト10.2とリスト7.15)のフォーム送信コードは、<%= form_for(@user) do |f| %>で全く同じ。
でもHTTPリクエストはPATCHとPOSTで別のものを使っています。
これはRailsで自動判別してくれているから。
その方法は@userがデータベースに存在する既存のユーザーか、それとも新規のユーザーかで判別しているそう。(Active Recordのnew_record?論理値メソッド)
$ rails console
>> User.new.new_record?
=> true
>> User.first.new_record?
=> false
form_for(@user)を使ってフォームを作ると、
- @user.new_record?がtrueのときにはPOST
- falseのときにはPATCH
を使ってくれるらしい。
ヘッダーに編集ページへのリンクの設置
Usersリソースが提供するRESTfulなルートを参考に以下のコードを_header.html.erbに追加すればOK。
<li><%= link_to "Settings", edit_user_path(current_user) %></li>
編集の成功失敗の分岐はcreateアクションほぼ同じ
class UsersController < ApplicationController
...
def create
@user = User.new(user_params)
if @user.save
log_in @user
flash[:success] = "Welcome to the Sample App!"
redirect_to @user
else
render 'new'
end
end
...
def update
@user = User.find(params[:id])
if @user.update_attributes(user_params)
flash[:success] = "Profile updated"
redirect_to @user
else
render 'edit'
end
end
end
タケシなりの演習の回答
リスト 10.5のパーシャルを使って、new.html.erbビュー (リスト 10.6) とedit.html.erbビュー (リスト 10.7) をリファクタリングしてみましょう (コードの重複を取り除いてみましょう)。ヒント: 3.4.3で使ったprovideメソッドを使うと、重複を取り除けます3。(関連するリスト 7.27の演習課題を既に解いている場合、この演習課題をうまく解けない可能性があります。
ぼくは7.27の演習問題を解いていたので、ちょっと注意が必要でした。
form_forの送り先が違うので、ここをprovideを使ってあげて、場合分けできるようにしてあげます。
new.html/erbの方は、もともと合ったほうの送信先signup_pathを使えばOK。
edit.html.erbの方は、送信先をupdateアクションにしたいので、7.1.2節にあるresouceで提供されるルートの表で確認。
よって、標準ではuser_pathの名前付きルートに送信しているとわかる。
だから答えはこんな感じ。
<%= form_for(@user, url: yield(:url)) do |f| %>
<%= render 'shared/error_messages', object: @user %>
<%= f.label :name %>
<%= f.text_field :name, class: 'form-control' %>
<%= f.label :email %>
<%= f.email_field :email, class: 'form-control' %>
<%= f.label :password %>
<%= f.password_field :password, class: 'form-control' %>
<%= f.label :password_confirmation %>
<%= f.password_field :password_confirmation, class: 'form-control' %>
<%= f.submit yield(:button_text), class: "btn btn-primary" %>
<% end %>
<% provide(:title, 'Sign up') %>
<% provide(:url, signup_path) %>
<% provide(:button_text, 'Create my account') %>
<h1>Sign up</h1>
<div class="row">
<div class="col-md-6 col-md-offset-3">
<%= render 'form' %>
</div>
</div>
<% provide(:title, 'Edit user') %>
<% provide(:button_text, 'Save changes') %>
<% provide(:url, user_path) %>
<h1>Update your profile</h1>
<div class="row">
<div class="col-md-6 col-md-offset-3">
<%= render 'form' %>
<div class="gravatar_edit">
<%= gravatar_for @user %>
<a href="http://gravatar.com/emails" target="_blank">Change</a>
</div>
</div>
</div>
リスト 10.9のテストに1行追加し、正しい数のエラーメッセージが表示されているかテストしてみてましょう。
テストのコードだと、エラーメッセージが4つ表示されるはず。
だからerror_messages id付きのdiv要素の中に、箇条書きのli要素が4つあることをテストしてあげればOK。
HTML要素のテストはassert_selectでできたので、答えはこんな感じ。
require 'test_helper'
class UsersEditTest < ActionDispatch::IntegrationTest
...
test "unsuccessful edit" do
...
assert_template 'users/edit'
assert_select "div#error_explanation li", 4
end
end
[Day10]まとめ
- 学習範囲:10.1〜10.1.4
- 学習時間:3時間
- 総学習時間:44時間40分
- 反省点:最近(特にDay8,9あたり)スピード意識しすぎて吸収効率微妙だった。ゆっくりでいいから、今日みたいにしっかり考えて取り組もう。
- 備考:特になし
今日はいつもより少なめ。
だけど、考える時間を増やすよりも、じっくり考えてゆっくり進むほうがいいと思った。
できるだけ考えて、前に進んでいこう。
読んでいただいている方、いつもありがとうございます!
初心者なもので、たまに間違った内容もあるかと思います。
その際にはコメントやTwitterでご指摘いただけると幸いです!
コメントを残す