关联请求规范失败 - Rails 5 API
Request Spec failing on Association - Rails 5 API
我有一个请求规范在具有关联的模型上失败;当我 binding.pry
进入它时,我可以使用相同的参数手动创建记录,但是当我通过 post '/path/model'
请求传递它们时,它失败并表示关联应该存在。很好-我希望关联是必需的。但是post
这个动作好像不能通过
# job model
belongs_to :worker
validates :title, presence: true
# worker model
has_many :jobs
# jobs controller
# POST /jobs
def create
@job = Job.create!(job_params)
json_response(@job, :created)
end
# jobs request spec
describe "POST /v1/jobs" do
context "when the request is valid" do
before {
post '/v1/jobs', params: {
title: "Whatever",
worker_id: Worker.first.id,
}
}
it "creates a job" do
puts request.body.read
puts response.body
expect(json["title"]).to eq("Whatever")
end
it "returns status code 201" do
expect(response).to have_http_status(201)
end
end
end
这些测试都失败了。上面 puts
语句的结果是:
title=Whatever&worker_id=21
{"message":"Validation failed: Worker must exist"}
如果我把 binding.pry
放在那里,下面会成功创建 Job
:
Job.create(title: "Whatever", worker_id: Worker.first.id)
我的迁移是:
# jobs migration
create_table :jobs do |t|
t.references :worker, index: true
t.text :title
end
# worker migration
create_table :workers do |t|
t.text :first_name
...
end
我在这里错过了什么?我知道 belongs_to
关联现在在 Rails 5 中是非可选的,但同样,我想要那个。所以我不想标记它 optional
只是为了让我的测试通过。有什么想法吗?
您似乎还没有为要使用的规范创建 Worker
。请记住,您的数据库在每个规范中都是空的,因此 Worker.first.id
将失败,因为数据库中没有工作人员。
在你的规范中你想创建一个工人(我使用 FactoryBot,同样的概念适用于固定装置或你正在使用的任何东西):
context "when the request is valid" do
let!(:worker) { create :worker }
before {
post '/v1/jobs', params: {
title: "Whatever",
worker_id: worker.id,
}
}
it "creates a job" do
puts request.body.read
puts response.body
expect(json["title"]).to eq("Whatever")
end
it "returns status code 201" do
expect(response).to have_http_status(201)
end
end
我使用了 let!
,因为这将强制在规范 运行 之前创建记录。现在 Worker.first.id
会找到那个工人,你就在路上!
你是对的,因为它是由 belongs_to
关联引起的 Rails 5.
默认情况下需要关联
我通常做的是让它成为创建的可选:belongs_to :worker, optional: :new_record?
然后编写一个测试以确保它确实被创建了。
原来这是控制器的问题;我使用的是严格参数,并且在允许的参数列表中没有 worker_id
。很容易被忽视,但这是一个陷阱!希望这对其他人有帮助,特别是因为关于 Rails 5 的 belongs_to
协会的所有建议都说,"just make it optional."
我有一个请求规范在具有关联的模型上失败;当我 binding.pry
进入它时,我可以使用相同的参数手动创建记录,但是当我通过 post '/path/model'
请求传递它们时,它失败并表示关联应该存在。很好-我希望关联是必需的。但是post
这个动作好像不能通过
# job model
belongs_to :worker
validates :title, presence: true
# worker model
has_many :jobs
# jobs controller
# POST /jobs
def create
@job = Job.create!(job_params)
json_response(@job, :created)
end
# jobs request spec
describe "POST /v1/jobs" do
context "when the request is valid" do
before {
post '/v1/jobs', params: {
title: "Whatever",
worker_id: Worker.first.id,
}
}
it "creates a job" do
puts request.body.read
puts response.body
expect(json["title"]).to eq("Whatever")
end
it "returns status code 201" do
expect(response).to have_http_status(201)
end
end
end
这些测试都失败了。上面 puts
语句的结果是:
title=Whatever&worker_id=21
{"message":"Validation failed: Worker must exist"}
如果我把 binding.pry
放在那里,下面会成功创建 Job
:
Job.create(title: "Whatever", worker_id: Worker.first.id)
我的迁移是:
# jobs migration
create_table :jobs do |t|
t.references :worker, index: true
t.text :title
end
# worker migration
create_table :workers do |t|
t.text :first_name
...
end
我在这里错过了什么?我知道 belongs_to
关联现在在 Rails 5 中是非可选的,但同样,我想要那个。所以我不想标记它 optional
只是为了让我的测试通过。有什么想法吗?
您似乎还没有为要使用的规范创建 Worker
。请记住,您的数据库在每个规范中都是空的,因此 Worker.first.id
将失败,因为数据库中没有工作人员。
在你的规范中你想创建一个工人(我使用 FactoryBot,同样的概念适用于固定装置或你正在使用的任何东西):
context "when the request is valid" do
let!(:worker) { create :worker }
before {
post '/v1/jobs', params: {
title: "Whatever",
worker_id: worker.id,
}
}
it "creates a job" do
puts request.body.read
puts response.body
expect(json["title"]).to eq("Whatever")
end
it "returns status code 201" do
expect(response).to have_http_status(201)
end
end
我使用了 let!
,因为这将强制在规范 运行 之前创建记录。现在 Worker.first.id
会找到那个工人,你就在路上!
你是对的,因为它是由 belongs_to
关联引起的 Rails 5.
我通常做的是让它成为创建的可选:belongs_to :worker, optional: :new_record?
然后编写一个测试以确保它确实被创建了。
原来这是控制器的问题;我使用的是严格参数,并且在允许的参数列表中没有 worker_id
。很容易被忽视,但这是一个陷阱!希望这对其他人有帮助,特别是因为关于 Rails 5 的 belongs_to
协会的所有建议都说,"just make it optional."