0

我正在尝试遵循 RailsTutorial 指南,但改为使用自己的应用程序。我对第 7 节的表格有疑问。

我的控制器:

  def update
    d = Deck.find(params[:id])
    d.title = params[:deck][:title]
    d.slug = params[:deck][:slug]
    d.category = params[:deck][:category]

    if d.save
      redirect_to deck_path(d), notice: "Deck saved successfully"
    else
      render :edit
    end

  end

我知道它离好的代码非常非常远,但我稍后会重构它(如果你有一个建议,我全神贯注,但我使用的是 Rails 3,所以我猜 Rails 4 的强大参数已经过时了)。

问题是当d.save不起作用(由于验证)时,使用render :edit.

现在,当我输入无效数据时,它会尝试重定向到show操作,然后崩溃,因为它没有任何数据要显示。
如果我在@deck = d上面添加render,它可以工作,但 url 仍然是show操作。

如果我的验证失败,我怎样才能保持在同一个 URL 上并显示我的错误消息?“更改 URL 但呈现相同页面”行为是否被接受为有效?

谢谢 !

如果您有兴趣查看其余代码,请访问:https ://github.com/cosmo0/TeachMTG/tree/remodel-decks

4

3 回答 3

3

实际上,当它失败时,您的网址不是“显示”,而是“更新”网址。

您的代码有效。

当您提交表单时,您的浏览器会向控制器#update 发送一个 POST 请求。

当更新失败时,您告诉更新操作“render :edit”。它的作用是在 :update 路由中呈现 :edit 动作。

更新路由使用与您的显示操作相同的 url:您可以在运行 'rake routes' 时检查这一点,唯一的区别是方法是 POST 用于 'update' 而 GET 用于 'show'

这就是为什么您认为它是浏览器中的显示 url 但实际上一切正常:您正在进行渲染 :edit 的更新操作。

(将您的更新操作告诉“render :edit”并不意味着您被重定向到 :edit 从 :update)

够清楚吗?

于 2013-08-24T11:32:13.567 回答
1

我认为您误解了宁静世界中正在发生的事情。当您进行更新时,URL 会发生变化,因为您的表单正在执行HTTP POST.

如果 d.save 有效,它会以 d 为对象重定向到您的 deck_path。如果失败,它不会更改浏览器中的 URL,而是呈现与edit操作相同的页面。

我猜在呼吁edit采取行动时,您会遇到以下情况:

@deck =  Deck.find(id)

您的渲染失败,因为您没有@deck在更新中分配变量。因此,您可以更改dto的所有实例@deck或使用您的解决方案 setting @deck = d

于 2013-08-24T11:35:11.070 回答
1

我相信您正在寻找respond_with方法。

于 2013-08-24T11:27:04.733 回答