我有一个模型项目和模型测试。项目有很多测试。
我的tests_controller
有:
def new
@project = Project.find(params[:project_id])
@test = @project.tests.new
end
def create
@project = Project.find(params[:project_id])
@test = @project.tests.create(test_params)
end
因此,在我的new.html.erb
中,我提供了一个调用new
的表单,当按下提交时,会调用create
。我很困惑,因为显然发生的事情是我在new
中创建了一个测试,在create
中创建了一个完全不同的测试。对于我想要实现的目标,正确的范例是什么?
我在new
中创建新测试的原因是因为我希望我的创建表单知道要创建的测试对象的id。
答案 0 :(得分:0)
create
操作应如下所示:
def create
@project = Project.find(params[:project_id])
@test = @project.test.create(params[:test])
if @test.save
redirect_to SOME_path, flash: { success: "Test added successfully" }
else
flash.now[:error] = "Something's gone wrong. Please try again!"
render 'new'
end
end
答案 1 :(得分:0)
#new
控制器操作中持久保存对象?HTTP请求一致性
所有#new
个操作都映射到GET请求,这些请求不应用于创建资源。创建资源可以通过两种方式完成:非幂等方式,使用映射到POST的#create
;和幂等方式,使用映射到PUT(或某些情况下为PATCH)的#update
。当您想要创建您已经知道其身份的资源时,后者就是您的选择。
<强>验证强>
验证背后的整个想法是应该在持久化数据之前应用。因此,在#new
操作中,我们通常将自己限制为实例化模型类,然后在#create
操作中我们可以至少有两个可能的响应 - 在验证已被清除时成功的响应和对象当我们在持久化对象时遇到错误时,它一直存在,并且是不成功的。
保持数据库远离空对象
#new
和#create
是不同操作的另一个原因是服务器可能会丢失与客户端之间的连接。而且,当发生这种情况时,您不希望在数据库中存在空对象,因为第二个操作永远不会出现。
那就是说,如果你仍然有充分的理由在要求输入用户输入和之前保留对象,那么你就不需要验证了,你不介意在数据库中有空对象,你可以通过完全跳过#new
动作来做到这一点,有点像这样:
def create
@project = Project.find(params[:project_id])
@test = @project.tests.create
end
def update
@project = Project.find(params[:project_id])
@test = @project.tests.update(test_params)
end