Ruby on rails Rails创建和新建不同的对象
我有一个模型项目和一个模型测试。这个项目有很多测试 我的Ruby on rails Rails创建和新建不同的对象,ruby-on-rails,Ruby On Rails,我有一个模型项目和一个模型测试。这个项目有很多测试 我的测试\u控制器具有: 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 因此,在我的
测试\u控制器
具有:
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
的表单,当按下submit时,就会调用create
。然而,我感到困惑,因为显然发生的事情是,我在new
中创建了一个测试,在create
中创建了一个完全不同的测试。我想要实现的正确范例是什么
我在
new
中创建新测试的原因是我希望我的创建表单知道要创建的测试对象的id。创建操作应该如下所示:
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
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
为什么Rails不在#new
控制器操作中持久化对象?
HTTP请求一致性
所有#新的操作都映射到GET请求,不应使用GET请求创建资源。创建资源有两种方式:非幂等方式,使用映射到POST的#create
;以及幂等方法,通过使用映射到PUT(在某些情况下映射到PATCH)的#update
。当您想要创建您已经知道其id的资源时,可以使用后者
验证
验证背后的整体思想是,在持久化数据之前应该应用验证。因此在#new
操作中,我们通常将自己限制为实例化模型类,然后在#create
操作中,我们至少可以有两种可能的响应——一种是在清除验证并持久化对象时成功响应,另一种是在持久化对象时出错时失败响应
保持数据库中没有空对象
#new
和#create
是不同操作的另一个原因是服务器可能会失去它们之间与客户端的连接。而且,当这种情况发生时,您不希望数据库中有一个空对象,因为第二个操作从未执行过
也就是说,如果您在请求用户输入之前仍然有充分的理由保留对象,并且您不需要验证,也不介意数据库中有空对象,那么您可以完全跳过#new
操作,类似这样:
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
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
它们是不同的对象,因为它们不会在请求之间持久化。但是在第一个操作中,您并没有实际创建测试,您只是实例化了测试类。你的问题到底是什么?@depa那么我如何在请求之间保持它们?典型的处理方式是什么?为什么要坚持?您没有数据在第一个操作中保存它,这只发生在第二个操作中,因为您有test_参数。这是处理这一问题的典型方式。@depa当我展示create表单时,我希望表单知道新测试对象的潜在id。这就是为什么在new
方法中我要创建一个测试对象。在实际将主键保存到数据库之前,您不会知道主键。您没有任何阻止您持久化空对象的验证?我遇到的问题是我正在使用([@project,test]..
,如果我不调用new,那么我就没有机会进行设置,@project和test都将为零,因此没有表单。但是你应该将表单基于新对象的空对象。你能告诉我你得到的确切错误消息吗?告诉Rails..我得到一个异常:表单中的第一个参数不能包含n nil或为空
,它指的是行的表单。好的,这就是为什么你在提问时总是要讲述整个故事。请尝试在你的\new
操作中简单地使用@test=test.new
。是的,但是现在当我在表单上点击submit时,我在new中创建的测试将在create方法中被忽略。我需要跟踪它的id。