回答編集履歴
3
回答を追記しました
answer
CHANGED
@@ -53,4 +53,83 @@
|
|
53
53
|
post project_tasks_url(@project), headers: headers, params: { task: new_task }
|
54
54
|
```
|
55
55
|
|
56
|
-
以上、参考になれば幸いです。
|
56
|
+
以上、参考になれば幸いです。
|
57
|
+
|
58
|
+
## コメントを受けての追記
|
59
|
+
|
60
|
+
> それが`project_tasks/url(@project)`にしているのですが、上記のようなエラーが出てしまいます。
|
61
|
+
> 該当のコードのURLは以下のようになります
|
62
|
+
> https://github.com/YouheiNozaki/Everyday-rails-v6/blob/main/spec/requests/tasks_request_spec.rb
|
63
|
+
|
64
|
+
コードの共有ありがとうございます!これだと手元でもエラーを再現できるので非常に助かります。
|
65
|
+
というわけで、僕もローカルで再現させてみました。
|
66
|
+
|
67
|
+
これ、前回のコメントですっかり見落としていましたが、RSpec側のパスではなく、Viewに書かれたパスの間違いですね。
|
68
|
+
しかも、ryusouさんの間違いではなくオリジナルのサンプルコードの間違いです。(Oh...????)
|
69
|
+
|
70
|
+
[https://github.com/everydayrails/everydayrails-rspec-2017/blob/90b22535d44ab626b82363335a227c5a1856a039/app/views/tasks/_task.json.jbuilder#L2](https://github.com/everydayrails/everydayrails-rspec-2017/blob/90b22535d44ab626b82363335a227c5a1856a039/app/views/tasks/_task.json.jbuilder#L2)
|
71
|
+
|
72
|
+
正しくはこうですね。
|
73
|
+
|
74
|
+
```diff
|
75
|
+
-json.url project_task_url([task.project, task], format: :json)
|
76
|
+
+json.url project_task_url(task.project, task, format: :json)
|
77
|
+
```
|
78
|
+
|
79
|
+
こうすればテストはパスするはずです。
|
80
|
+
|
81
|
+
### コントローラースペックでエラーが起きなかった理由
|
82
|
+
|
83
|
+
ではなぜViewに不具合があったのにコントローラースペックの方はパスしたのでしょうか?
|
84
|
+
これはコントローラースペックはデフォルトでViewをレンダリングしないためです。
|
85
|
+
そのため、コントローラースペックという名前の通り「コントローラーは異常なし!だからヨシ!(Viewは知らん!)」となってしまったわけです。
|
86
|
+
|
87
|
+
ただし、`render_views`というメソッドを呼びだしておくと、コントローラースペックでもViewのレンダリングを強制することができます。
|
88
|
+
こうするとコントローラースペックでもエラーが発生するようになります。
|
89
|
+
|
90
|
+
```diff
|
91
|
+
require 'rails_helper'
|
92
|
+
|
93
|
+
RSpec.describe TasksController, type: :controller do
|
94
|
+
+ render_views
|
95
|
+
include_context "project setup"
|
96
|
+
```
|
97
|
+
|
98
|
+
実行結果
|
99
|
+
|
100
|
+
```
|
101
|
+
Failures:
|
102
|
+
|
103
|
+
1) TasksController#create responds with JSON formatted output
|
104
|
+
Failure/Error: json.url project_task_url([task.project, task], format: :json)
|
105
|
+
|
106
|
+
ActionView::Template::Error:
|
107
|
+
No route matches {:action=>"show", :controller=>"tasks", :format=>:json, :project_id=>[#<Project id: 1, name: "Project 2", description: "A test project.", due_on: "2021-03-06", created_at: "2021-02-27 07:53:57.565109000 +0000", updated_at: "2021-02-27 07:53:57.565109000 +0000", user_id: 1, completed: nil>, #<Task id: 1, name: "New test task", project_id: 1, completed: nil, created_at: "2021-02-27 07:53:57.574235000 +0000", updated_at: "2021-02-27 07:53:57.574235000 +0000">]}, missing required keys: [:id]
|
108
|
+
Did you mean? project_tasks_url
|
109
|
+
project_task_path
|
110
|
+
project_tasks_path
|
111
|
+
new_project_task_url
|
112
|
+
# ./app/views/tasks/_task.json.jbuilder:2:in `_app_views_tasks__task_json_jbuilder___3745737086157069224_66100'
|
113
|
+
# ./app/views/tasks/show.json.jbuilder:1:in `_app_views_tasks_show_json_jbuilder__4444021816594691676_66060'
|
114
|
+
# ./app/controllers/tasks_controller.rb:34:in `block (2 levels) in create'
|
115
|
+
# ./app/controllers/tasks_controller.rb:31:in `create'
|
116
|
+
# ./spec/controllers/tasks_controller_spec.rb:20:in `block (3 levels) in <top (required)>'
|
117
|
+
# ------------------
|
118
|
+
# --- Caused by: ---
|
119
|
+
# ActionController::UrlGenerationError:
|
120
|
+
# No route matches {:action=>"show", :controller=>"tasks", :format=>:json, :project_id=>[#<Project id: 1, name: "Project 2", description: "A test project.", due_on: "2021-03-06", created_at: "2021-02-27 07:53:57.565109000 +0000", updated_at: "2021-02-27 07:53:57.565109000 +0000", user_id: 1, completed: nil>, #<Task id: 1, name: "New test task", project_id: 1, completed: nil, created_at: "2021-02-27 07:53:57.574235000 +0000", updated_at: "2021-02-27 07:53:57.574235000 +0000">]}, missing required keys: [:id]
|
121
|
+
# Did you mean? project_tasks_url
|
122
|
+
# project_task_path
|
123
|
+
# project_tasks_path
|
124
|
+
# new_project_task_url
|
125
|
+
# ./app/views/tasks/_task.json.jbuilder:2:in `_app_views_tasks__task_json_jbuilder___3745737086157069224_66100'
|
126
|
+
```
|
127
|
+
|
128
|
+
`rails s`で起動したサンプルアプリケーションではTaskの作成はJSONではなくHTMLリクエストで実行されることもあり、JSONレスポンスに不具合が隠れていることを検知できていませんでした。どうもすみません????♂️
|
129
|
+
|
130
|
+
というわけで、この件は原著者のAaronさんにフィードバックしておきました。
|
131
|
+
|
132
|
+
[\_task.json.jbuilder has invalid arguments for project\_task\_url · Issue \#112 · everydayrails/everydayrails\-rspec\-2017](https://github.com/everydayrails/everydayrails-rspec-2017/issues/112)
|
133
|
+
|
134
|
+
おかげさまで長年誰も気づいていなかった不具合を見つけることができました。
|
135
|
+
どうもありがとうございました!!
|
2
post先のURLを修正
answer
CHANGED
@@ -50,7 +50,7 @@
|
|
50
50
|
ここまで来れば答えはもうお分かりかと思いますが、正しくは`projects_url`ではなく、`tasks_url`を指定することです。ただ、この場合は単純に`projects_url`を置き換えるだけでなく、次のように書く必要があるかもしれません。(動作未確認)
|
51
51
|
|
52
52
|
```ruby
|
53
|
-
post
|
53
|
+
post project_tasks_url(@project), headers: headers, params: { task: new_task }
|
54
54
|
```
|
55
55
|
|
56
56
|
以上、参考になれば幸いです。
|
1
changed URL
answer
CHANGED
@@ -45,7 +45,7 @@
|
|
45
45
|
|
46
46
|
実際、エラーメッセージに表示されている `Failure/Error: params.require(:project).permit(:name, :description, :due_on)` は、ProjectsController内のコードです。
|
47
47
|
|
48
|
-
https://github.com/
|
48
|
+
[https://github.com/everydayrails/everydayrails-rspec-2017/blob/63e38f87c8edfdfb5861fa628429651f62c8492e/app/controllers/projects_controller.rb#L83](https://github.com/everydayrails/everydayrails-rspec-2017/blob/63e38f87c8edfdfb5861fa628429651f62c8492e/app/controllers/projects_controller.rb#L83)
|
49
49
|
|
50
50
|
ここまで来れば答えはもうお分かりかと思いますが、正しくは`projects_url`ではなく、`tasks_url`を指定することです。ただ、この場合は単純に`projects_url`を置き換えるだけでなく、次のように書く必要があるかもしれません。(動作未確認)
|
51
51
|
|