0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Rspecでテストを書いているとき、下記の実装に関してpathの引数にtask.projectが使われていることに疑問を感じておりました。

describe 'Task詳細' do
  context '正常系' do
    it 'Taskが表示されること' do
      visit project_task_path(task.project, task)
      #project_task_path(project, task) ではだめなの?
      expect(page).to have_content(task.title)
      expect(page).to have_content(task.status)
      expect(page).to have_content(task.deadline.strftime('%Y-%m-%d %H:%M'))
      expect(current_path).to eq project_task_path(task.project, task)
    end
  end
end

#前提条件
taskとprojectがassociationの関係を持つ。

class project < ApplicationRecord
  has_many tasks
end
class Task < ApplicationRecord
  belongs_to :project
end

#考え方
まず考えるべきなのが、どのようなURLが生成されるべきかということ。

ここではTaskの詳細画面なのでURL/project/id/task/id/show となるべきですね。

次にtaskとprojectがassociationの関係を持つということ。

class project < ApplicationRecord
  has_many tasks
end
class Task < ApplicationRecord
  belongs_to :project
end

これによりtaskはproject(親)のidを持つことになります。

実際にpathの引数のレコードを調べるとこんな感じ。

(byebug) project
#<**Project id: 1**, name: "dolorum", status: "todo", release_date: "2019-05-24", created_at: "2021-06-28 14:23:59", updated_at: "2021-06-28 14:23:59">
(byebug) task
#<Task id: 3, title: "Task", status: "done", deadline: "2019-10-17 15:00:00", completion_date: nil, description: nil, **project_id: 2**, created_at: "2021-06-22 10:38:01", updated_at: "2021-06-22 10:38:01">
(byebug) task.project
#<**Project id: 2**, name: "repudiandae", status: "todo", release_date: "2019-11-05", created_at: "2021-06-22 10:38:01", updated_at: "2021-06-22 10:38:01">

注目すべきはproject_id ****の値。

project_id: 1に対しtaskはproject_id: 2を持っていますね。

これはassociationの関係とは言えません。

実際project_task_path(project, task)でもURL自体は生成されますが、これではproject_idが異なるため、生成されるURLのidはassociationの関係ではなくなってしまいます。

project_task_path(project, task)
=> /project/1/task/3

project_task_path(task.project, task)のようにしてproject(親)のidをtask.projectの返り値から取得することで、生成されるURLはassociationの関係を保つことができます。

project_task_path(task.project, task)
=> /project/2/task/3

#引数の順番を入れ替てみる
以下のような結果から、pathの引数はassociationで定義したことなど関係なく、引数に指定した順番の通りにidを渡すようです。

project_task_path(task.project, task)
=> /project/2/task/3

# 引数の順番を入れ替えた結果
project_task_path(task, task.project)
=> /project/3/task/2

なので、引数を指定する際は定義したassociationの関係や、実際のブラウザの挙動を意識して、引数を指定してあげる必要があります。

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?