redirect_to对RESTful应用程序不起作用?

时间:2009-12-21 22:43:12

标签: ruby-on-rails rest

作为一个长期使用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更喜欢直接调用操作的想法?

3 个答案:

答案 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人,但重定向的原因是语言无关:

  1. 如果他们进行页面刷新,他们就不会那么讨厌“重新发送数据?”弹出窗口。
  2. 这为您正在查看的页面提供了一个完全干净的RESTful URL。如果您使用POST可能并不重要,但如果使用GET进行更新,那么您肯定想要摆脱任何悬挂的参数。