我有一个资源叫图书。它在我的路线文件中被正确地列为资源。
我有一个新的行动,它赋予了新的观点以标准:
@book = Book.new
在模型上,有一些属性是通过存在来验证的,因此如果保存操作失败,将生成错误。
在我的控制器中:
@book = Book.create
... # some logic
if @book.save
redirect_to(@book)
else
render :new
end
这是相当标准的;使用render:new的基本原理是将对象传递回视图,并报告错误、重新填充表单条目等。
这是可行的,除了每次我被送回表单(通过render:new)时,我的错误都会显示出来,但我的URL是INDEX URL,也就是
/books
而非
/books/new
这也是我最初开始的地方。我看过其他几个关于这个问题的帖子,但是没有答案。至少,人们会认为它会让你登陆/books/create,我也有一个视图文件(在这个例子中与new相同)。
我可以这样做:
# if the book isn't saved then
flash[:error] = "Errors!"
redirect_to new_book_path
但是,@book数据和错误消息沿着丢失了,这是拥有表单和操作等的全部要点。
为什么render:new会让我登陆到/books,我的索引操作,而通常这个URL会调用INDEX方法,列出所有的书?
6条答案
按热度按时间6yjfywim1#
实际上,它 * 是 * 把你带到创建路径。它在
create
操作中,路径是/books
,使用HTTP方法POST。这看起来和索引路径/books
一样,但是索引路径使用HTTP方法GET。Rails路由代码在决定调用哪个操作时考虑该方法。验证失败后,你仍然在创建操作中,但是呈现的是new
视图,这有点混乱,但是像render :new
这样的行实际上根本不调用新操作;它仍然在运行create操作,并告诉Rails呈现新的 view。np8igboo2#
我刚开始使用Rails-Tutorial,也遇到了同样的问题。解决方案很简单:如果您在提交表单(有错误)后需要相同的URL,只需将新建和创建操作合并到一个操作中即可。
这是我的代码的一部分,它使这成为可能(希望它能帮助一些人^^)
routes.rb(为new-action添加后路由):
控制器:
new.html.erb:
ukxgm1gy3#
只是有同样的问题,所以也许有一天这可能会对某人有所帮助。你基本上要做3个调整才能让这个东西工作,虽然我的解决方案仍然不理想。
1)在创建操作中:
2)在新操作中:
3)无论在哪里解析flash哈希,都要确保过滤掉flash[:book]。
--〉显示正确的URL,保存表单数据。不过,我不喜欢把用户对象放到flash哈希中,我认为这不是它的目的。有没有人知道更好的地方把它放进去?
x7rlezfr4#
它不会让你到达
/books/new
,因为你是通过发布到/books/
来创建资源的。当你的创建失败时,它只是呈现新的操作,而不是重定向到新的操作。正如@MrYoshiji上面所说,你可以尝试重定向到新的操作,但这真的很低效,因为你会创建另一个HTTP请求并往返于服务器。只是为了改变url。在这一点上,如果它有关系,你可能会使用javascript改变它。e7arh2l65#
它可以通过使用相同的网址,但不同的方法为新的和创建行动修复。
在路由文件中,可以使用以下代码。
现在,您的新页面将呈现在url
书籍/公共路径字符串
如果验证后出现任何错误,URL仍将相同。
也在表单中使用
使用了
选择您喜欢的 common_path_string。
o8x7eapl6#
如果客户端验证失败,您仍然可以在呈现新视图时输入所有字段。服务器端错误沿着会输出到客户端。重新提交时,仍会运行创建操作。
在books_controller.rb中
在新的.html.erb中