LoginSignup
0
0

More than 3 years have passed since last update.

Railsチュートリアル10章まとめ

Last updated at Posted at 2021-03-21

10.1 ユーザーを更新する

ユーザーを更新する行為は、新規ユーザーの作成に似ている。

アクション リクエストに応答
新規作成 new POSTに対してcreate
更新 edit PATCHに対してupdate

10.1.1編集フォーム

まずやるべきは、Usersコントローラーにeditアクションを追加し、それに対応するeditビューを実装。
ルーティングはresources :usersのおかげで有効になっている。

Railsチュートリアル 表7.1を確認すると、ユーザー編集ページのURLは/users/1/editとなっている。
ここで、ユーザーidを取得するために用いるのが、params[:id]
paramとは、Railsで送られてきた値を取得するメソッド

app/controllers/users_controller.rb
  def edit
    @user = User.find(params[:id])
  end

ユーザーのeditアクション

app/views/users/edit.html.erb
<% provide(:title, "Edit user") %>
<h1>Update your profile</h1>

<div class="row">
  <div class="col-md-6 col-md-offset-3">
    <%= form_with(model: @user, local: true) do |f| %>
      <%= render 'shared/error_messages' %>

      <%= 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, "Confirmation" %>
      <%= f.password_field :password_confirmation, class: 'form-control' %>

      <%= f.submit "Save changes", class: "btn btn-primary" %>
    <% end %>

    <div class="gravatar_edit">
      <%= gravatar_for @user %>
      <a href="https://gravatar.com/emails" target="_blank">change</a>
    </div>
  </div>
</div>

ユーザーのeditビュー
ここでは、formの部分で、大部分がユーザー作成画面とかぶっているので、パーシャルでまとめるのが良い。

また、@userインスタンス変数を使って、idを取得し編集ページを表示している。

HTML
<form accept-charset="UTF-8" action="/users/1" class="edit_user"
      id="edit_user_1" method="post">
  <input name="_method" type="hidden" value="patch" />
  .
  .
  .
</form>

WebブラウザではそのままではPATCHリクエストを送信できない。
そこで以下のコードで「偽装」している。

<input name="_method" type="hidden" value="patch" />

リスト 10.2のform_with(@user)のコードは、リスト 7.15のコードと完全に同じである。
ここでは、Active Recordnew_record論理値メソッドでPOSTリクエストとPATCHリクエストを区別している。

$ rails console
>> User.new.new_record?
=> true
>> User.first.new_record?
=> false

true→POST
false→PATCH

最後に、ナビゲーションのリンクを実装

<%= link_to "Settings", edit_user_path(current_user) %>

edit_user_pathもUsersリソースのおかげで使用可能。
current_userはヘルパーメソッド(9章で実装)

10.1.2 編集の失敗

ゴールはupdateメソッドの実装。

app/controllers/users_controller.rb
  def update
    @user = User.find(params[:id])
    if @user.update(user_params)
      # 更新に成功した場合を扱う。
    else
      render 'edit'
    end
  end

抑えておきたいのは、updateの呼び出しにuser_paramsを使っている点。
これはStrong Parametersというテクニック

user_paramsメソッドはx Usersコントローラー内部でのみ実行され、Web経由で外部ユーザーに晒される心配はなし。属性の許可を制限することで管理者権限を乗っ取られることを防ぐ。
(詳しくは7.3.2参照)

  private

    def user_params
      params.require(:user).permit(:name, :email, :password,
                                   :password_confirmation)
    end
end

10.1.3 編集失敗時のテスト

統合テストを行う

$ rails generate integration_test users_edit
      invoke  test_unit
      create    test/integration/users_edit_test.rb

コマンドで統合テストを生成

まずは、編集失敗時のテストから。
流れとしては、編集ページにアクセス→editビューが描画されるか確認→無効な情報を送信→再度editビューが描画される

test/integration/users_edit_test.rb

require 'test_helper'

class UsersEditTest < ActionDispatch::IntegrationTest

  def setup
    @user = users(:michael)
  end

  test "unsuccessful edit" do
    get edit_user_path(@user)
    assert_template 'users/edit'
    patch user_path(@user), params: { user: { name:  "",
                                              email: "foo@invalid",
                                              password:              "foo",
                                              password_confirmation: "bar" } }

    assert_template 'users/edit'
  end
end

ここでPATCHリクエストを送るためにpatchメソッドを使用している。
これはget,postメソッド等と同様に、HTTPリクエストを送るためのもの。
(HTTPリクエストとは、クライアント側からWebサーバーにリクエストする際送信するもの)

0
0
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
0
0