作为一个长期使用Ruby和Rails的用户,直到今天才真正想到Rails中的get-and-redirect模式。典型的例子是调用create()动作,然后将用户重定向到show()动作以显示新创建的项目:
class JournalEntries def index @entries = JournalEntry.all end def create @entry = JournalEntry.new( :name => "to-do list" ) @entry.save redirect_to :action => "index" end end
但是,这有一个固有的缺点,即您的网络流量增加了一倍。这既会降低用户的网站体验速度,也会增加带宽费用。
那么为什么不这样做呢:
def create @entry = JournalEntry.new( :name => "to-do list" ) @entry.save index
输出相同,无需额外开销。但除此之外,还有一个更实质的问题:redirect_to只能使用GET重定向。这会导致使用四种不同HTTP方法的RESTful应用程序出现重大问题。
就我而言,我希望用户能够调用/ journals / 8并使用该ID检索日记。如果找不到,我想创建一个新的空日志对象。在任何一种情况下,Journal对象都将被发送给调用者。
请注意,RESTful Rails中的create()方法是从“POST / players”路由的。但是由于redirect_to(和底层HTTP重定向)只能发送GET请求,它实际上会重定向到“GET / players”,这是index()方法。这种行为显然是错误的。
我能想到的唯一解决方案是简单地调用create()而不是redirect_to(),如上例所示。它似乎工作正常。
有关为什么redirect_to更喜欢直接调用操作的想法?
答案 0 :(得分:2)
如果他们进行页面刷新,他们就不会那么烦人的“重新发送数据?”弹出
这不仅仅是弹出窗口令人讨厌(并且对大多数用户没有意义) - 如果用户点击“是,重新执行POST”,他将最终创建另一个日记帐分录(或其他)。
此外,由于用户无法复制/重复使用,因此读取/posts/create
而不是/posts
的网址很烦人。
答案 1 :(得分:2)
正如你所指出的那样。您重定向到GET请求,这在REST方面是正确的(仅使用POST / PUT进行更新,仅使用GET获取数据)。
重定向肯定会给重定向带来一点开销,但由于除了POST数据和重定向(只是将新url发送到浏览器)之外,浏览器和服务器之间实际上没有发送任何数据,所以我不赞成我认为带宽问题值得关注。
但另一方面,你不应该重定向到/ journals(通过调用redirect_to :index
),你应该将它重定向到新创建的日记条目(通过调用redirect_to @entry
),如果你设置它将会起作用例如,map.resources :journals
<强>更新强>
我认为,如果在不存在日志时创建日记,则应该要求用户提供更多输入。你创建这个条目的原因是什么?该条目应该包含一些来自用户的文本或其他输入,因此我认为从REST(和rails)的角度来看,您应该将其重定向到new()
方法(带有GET请求),用户可以在其中输入附加信息,然后将输入POST并创建条目,然后重定向到新创建的条目。
如果您没有任何需要输入的额外信息,我不确定如何以RESTful方式执行此操作,但我可能已经通过将创建逻辑放在一个单独的方法中来完成它会从create()
和show()
方法调用,然后继续使用show()
,而不是重定向,但也不会调用资源方法。
答案 2 :(得分:0)
我是Python / Django人,但重定向的原因是语言无关: