Railsチュートリアル第10章10.1.2でtestが通らなかった話

# 問題

Railsチュートリアル第10章に入りました。

　↓

「10.1.1 編集フォーム」の演習まで終わりました。
（usersの`new.html.erb`と`edit.html.erb`の共通ビューを`_form.html.erb`にパーシャルとしてまとめ終わった）

　↓

「10.1.2 編集の失敗」に進みました。
「リスト 10.8: ユーザーのupdateアクションの初期実装」やりました。
下のようにコンソールでテストしました。

```terminal
$ rails test
```

　↓

意図しないエラーが返ってきます。えっ、なんで？

```terminal
$ rails t
Running via Spring preloader in process 34158
Started with run options --seed 32068

 FAIL["test_invalid_signup_information", UsersSignupTest, 0.5963140000094427]
 test_invalid_signup_information#UsersSignupTest (0.60s)
        Expected at least 1 element matching "form[action="/signup"]", found 0..
        Expected 0 to be >= 1.
        test/integration/users_signup_test.rb:20:in `block in <class:UsersSignupTest>'

  33/33: [=================================================] 100% Time: 00:00:00, Time: 00:00:00

Finished in 0.68099s
33 tests, 84 assertions, 1 failures, 0 errors, 0 skips
```

（最下行のtests, assertionsの数はこのエラーが初めて明らかになった時点のものとは違いますのでご了承を）

# 原因

「10.1.1 編集フォーム」の演習の**Railsチュートリアルのコードが悪い**。（と思ってる）

パーシャルにまとめる前はpathの指定がされているけど、`_form.html.erb`にまとめた後ではpathが指定されていない。
たぶんだけど、newページでsubmitボタンが押され、遷移する先のURLがtestに書いてあるものと違うからエラーが出てる。


# 解消方法

`_form.html.erb`にpathを明示してあげる。

ただし！
`new.html.erb`と`edit.html.erb`では求められるpathが違うため、
それぞれにあったpathを`_form.html.erb`に渡してあげる必要がある。

# コード

##　Railsチュートリアルのコード（間違っている方）

```erb:app/views/users/_form.html.erb
<%= form_for(@user) 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 %>
```

```erb:app/views/users/new.html.erb
<% provide(:title, 'Sign up') %>
<% 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>
```

```erb:app/views/users/edit.html.erb
<% provide(:title, 'Edit user') %>
<% provide(:button_text, 'Save changes') %>
<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>
```

## 上手く動作するコード

↓　1行目でパスを渡してあげている

```erb:app/views/users/_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 %>
```

↓　3行目でパスを指定している

```erb:app/views/users/new.html.erb
<% provide(:title, 'Sign up') %>
<% provide(:button_text, 'Create my account') %>
<% provide(:url, signup_path) %>
<h1>Sign up</h1>
<div class="row">
  <div class="col-md-6 col-md-offset-3">
    <%= render 'form' %>
  </div>
</div>
```

↓　3行目でパスを指定している


```erb:app/views/users/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" ref="noopener">Change</a>
    </div>
  </div>
</div>
```

# 最後に

Rails初心者なので間違いがあるかもしれません。その時はご指摘をお願いいたします。

一応今回の対応でエラーは解消されることは確認済みですので、同じエラーで困っている方のお力になれば幸いです。