[Day10 Rails Tutorial]第十章途中|ユーザーの情報を更新可能に![10.1〜10.1.4]

Day10です!

今日もがんばっていきましょー!

読んでいただいている方、いつもありがとうございます!

初心者なもので、たまに間違った内容もあるかと思います。

その際にはコメントやTwitterでご指摘いただけると幸いです!

 

[Day10]第十章10.1〜10.1.4作業ログ

第十章はユーザーの更新、表示、削除の実装

第十章はユーザーの更新、表示、削除の実装です。

具体的には、以下の4つのアクションの実装。

  • edit
  • update
  • index
  • destroy

まずは自分のユーザー情報を編集できるようにする。

次に、すべてのユーザーを表示するページの作成。

あとは、認可したユーザーに限り、ユーザーの削除ができるようにする。

こんな流れでやっていきます。

 

編集ページの作成

editアクションで、現在のログインユーザーを所得してあげる。

URLが”/users/5/edit”みたいにユーザーIDが含まれているので、params[:id]でとってこれる。

users_controller.rb
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.html.erb
<%= 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 %>
new.html.erb
<% 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>
edit.html.erb
<% 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でできたので、答えはこんな感じ。

users_edit_test.rb
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でご指摘いただけると幸いです!

 

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です