我正在尝试遵循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
,则会有效,但网址仍然是show
。
如果我的验证失败,我如何保持相同的URL并显示我的错误消息? “更改URL但呈现相同页面”行为是否被视为有效?
谢谢!
如果您有兴趣查看其余代码,请点击此处:https://github.com/cosmo0/TeachMTG/tree/remodel-decks
答案 0 :(得分:3)
实际上当它失败时你的网址不是'show',它就是'更新'网址。
您的代码有效。
当您提交表单时,您的浏览器会向控制器#update发送POST请求。
更新失败时,您将更新操作告知“渲染:编辑”。它的作用是在:update route中呈现:edit动作。
更新路线使用与您的展示操作相同的网址: 你可以在运行'rake routes'时查看这个,唯一的区别是该方法是POST'for update'vs GET for'show'
这就是为什么你认为它是浏览器中的show url但实际上一切正常:你正在进行渲染的更新操作:编辑。
(将您的更新操作告诉'渲染:编辑'并不意味着您被重定向到:编辑回来:更新)
这是否足够清楚?
答案 1 :(得分:1)
我相信您正在寻找respond_with方法。
答案 2 :(得分:1)
我认为你误解了宁静世界正在发生的事情。当您进行更新时,网址正在发生变化,因为您的表单正在执行HTTP POST
。
如果d.save工作,它会重定向到你的deck_path,d为对象。如果失败,则不会更改浏览器中的URL,而是呈现与edit
操作相同的页面。
我猜你在edit
行动的呼吁中有类似的东西:
@deck = Deck.find(id)
您的渲染失败,因为您的更新中没有分配@deck
变量。因此,您可以将d
的所有实例更改为@deck
,也可以使用设置@deck = d
的解决方案。