Closed yoshimitsu41 closed 5 years ago
編集ボタンを押すとエラーがでて解決方法がわかりません。
まずエラー文言等をそのまま貼り付けて頂きたいです:bow: 後ソースコードはGitHubリンクを貼り付けてもらった方が良いかもです。コピペミスとかもあるので:bow:
$ bundle exec rails routes | grep client
した結果ってどうなりますか?
後ソースコードはGitHubリンクを貼り付けてもらった方が良いかもです。コピペミスとかもあるので🙇
https://github.com/yoshimitsu41/greenhill.git
$ bundle exec rails routes | grep client した結果ってどうなりますか?
root GET / clients#index
client_comments GET /clients/:client_id/comments(.:format) comments#index
POST /clients/:client_id/comments(.:format) comments#create
new_client_comment GET /clients/:client_id/comments/new(.:format) comments#new
edit_client_comment GET /clients/:client_id/comments/:id/edit(.:format) comments#edit
client_comment GET /clients/:client_id/comments/:id(.:format) comments#show
PATCH /clients/:client_id/comments/:id(.:format) comments#update
PUT /clients/:client_id/comments/:id(.:format) comments#update
DELETE /clients/:client_id/comments/:id(.:format) comments#destroy
client_agreements GET /clients/:client_id/agreements(.:format) agreements#index
POST /clients/:client_id/agreements(.:format) agreements#create
new_client_agreement GET /clients/:client_id/agreements/new(.:format) agreements#new
edit_client_agreement GET /clients/:client_id/agreements/:id/edit(.:format) agreements#edit
client_agreement GET /clients/:client_id/agreements/:id(.:format) agreements#show
PATCH /clients/:client_id/agreements/:id(.:format) agreements#update
PUT /clients/:client_id/agreements/:id(.:format) agreements#update
DELETE /clients/:client_id/agreements/:id(.:format) agreements#destroy
clients GET /clients(.:format) clients#index
POST /clients(.:format) clients#create
new_client GET /clients/new(.:format) clients#new
edit_client GET /clients/:id/edit(.:format) clients#edit
client GET /clients/:id(.:format) clients#show
PATCH /clients/:id(.:format) clients#update
PUT /clients/:id(.:format) clients#update
DELETE /clients/:id(.:format) clients#destroy
になります!
ありがとうございます:bow:
url:clients_path
をフォームで指定していますがその定義で実行されるアクションってroutesで出力したアクションのどれになるかわかりますか?
url:clients_path をフォームで指定していますがその定義で実行されるアクションってroutesで出力したアクションのどれになるかわかりますか?
すみません。 わからないです。
views/agreements/_form.html.erb
<%= form_for @comment, url:clients_path, :html => { :class => "form-horizontal comment" } do |f| %>
のurl:clients_pathのことですよね?
edit画面は下記です。
update agreementのボタンをクリックするとルーティングエラーになります。
url:edit_client_agreement_path に変更してもルーティングエラーになりました。
ですです! お、わからないのは全然おkですがここは必須で理解しておきたいところなのでこれを機に理解しましょう!
No route matches [PATCH] "/clients"
のところは
PATCHメソッドの /clients がリクエストされているということです。これがform_forでリクエスト先として生成されています。
clientsで生成されているルーティングを確認すると下記になるので GET
と POST
しかなくてPATCH
になっているものがないですよね。それでルーティング定義がないのでエラーになっています。
clients GET /clients(.:format) clients#index
POST /clients(.:format) clients#create
じゃあ今回生成したいリクエストに使用するURL(endpointとか言ったりします)を生成するためにはどうしたら良いのかという話になるのですが、まずルーティング定義からルーティングしたい先のcontrollerとアクションを探します。
今回だと agreements_controllerのupdateアクションを実行したいと思うので agreements#update
となっているところを探します。
client_agreement GET /clients/:client_id/agreements/:id(.:format) agreements#show
PATCH /clients/:client_id/agreements/:id(.:format) agreements#update
PUT /clients/:client_id/agreements/:id(.:format) agreements#update
二つあるんですが、これは昔からの名残でPUTの方が残っているので基本的にはPATCHを利用すれば良いです。なので client_agreement_path
というurl(endpoint)とmethodはpatchを指定すれば良いです。
Rails5系からはform_forが非推奨になっているようなのでform_withを使ってあげると良いと思います。 https://techracho.bpsinc.jp/hachi8833/2017_05_01/39502
form_with @agreement, url: client_agreement_path, scope: :patch do |f|
みたいな書き方になるのかな。
ただ url: client_agreement_path, scope: :patch
のところは本来Railsが自動で判別してくれるので不要かもしれません。
あと気になったのは記載していただいたform_forで@commentインスタンスを利用しようとしている点?ですかね。@agreementの情報を編集するのにcommentは関係ないのでは?と思ったりしました。
ついでに
url:edit_client_agreement_path に変更してもルーティングエラーになりました。
のところはeditアクションを実行するパスにルーティングしようとしていると思うのですが、editアクションって編集画面を表示するためのアクションなのでそこにルーティングしても意味ないと思いました:bow:
ちょっと難しいかもですが一旦ご確認くださいmm 難しいところあれば追加で質問ください:bow:
なんとなくですが、理解しました。
form_with @agreement, url: client_agreement_path, scope: :patch do |f|
で試したところエラーが出ました。 ※url: client_agreement_path, scope: :patchの無しのバージョンも試しましたがエラーでした。
しかし
<%= form_for @agreement, url:client_agreement_path, :html => { :class => "form-horizontal agreement" } do |f| %>
で試したところエラーなく更新ができました。 ありがとうございます!
ああ、form_withのパラメータの指定の仕方が間違ってましたね
form_with model: @agreement, url: client_agreement_path, scope: :patch do |f|
とかが正しいのか。
scopeはなくてもRailsが更新する処理かどうか判定してルーティングしてくれます。 判定する基準は @agreementのidが設定されているかどうかで
設定されていない => 新規作成と判定してcreateアクションを実行 設定されている => 更新と判定してupdateアクションを実行
という挙動になります。 form_forは非推奨の記述になって今後なくなっていくのでなるべく使わない方が良いですね:smile:
ありがとうございます!
@yoshimitsu41 これとか参考になるので復習してみると良いと思います:bow: https://diveintocode.jp/tips/routing01
概要
client(クライアント) agreement(契約) というモデルがあります。
client 1 - * agreement の関係です。
困っていること
クライアントに紐付いた契約を追加できるように実装して、追加や削除はできています。 しかし、編集ボタンを押すとエラーがでて解決方法がわかりません。
action="/clients"
の部分がaction="clients/1/agreements/8"
になっていないと情報が渡らないと考えているのですがどのようにすればいいのかわかりません。ご教授お願いします。