使用RESTful会话在控制器之间传递数据

时间:2009-05-09 08:36:57

标签: ruby-on-rails controller

我在我的代码中使用 hideous 模式,我知道必须有更好的方法来执行此操作。帮助我重新思考我正在做的事情。

我的网站是一种讨论论坛。所有对讨论的回复都在DiscussionsController#show page,inline。

上完成

但有些回复无效 - 例如,如果您尝试发布没有文字的回复,则会返回带有错误消息的DiscussionsController#show。

以下是我如何实施此工作流程的简要概述:

  1. 用户转到DiscussionsController #show。这个模板上有一个回复表格。没有明确的RepliesController#new action。
  2. 用户提交回复表单,该表单已发布到replies_path并在RepliesController #create中处理。
  3. RepliesController #create无法保存回复,因为它无效(回复中的validates_length_of使对象无效)。
  4. RepliesController#create将回复对象放入会话[:new_reply]并重定向到用户来自的discussion_path。
  5. DiscussionsController #show处理会话对象...
  6. 像这样:

    if session[:new_reply]
      @new_reply = session[:new_reply]
      session.delete(:new_reply)
    end
    

    现在show.html.erb有一个新重新生成的@new_reply对象来检查错误。

    这有明显的错误 - 你不应该在会话中存储整个对象。但是,由于我们试图保存在RepliesController #creore中的Reply对象永远不会保存,如何在控制器动作调用之间保留它?

    或者如果有更大的设计解决方案,请随意分享。这太难看了,这伤害了我。感谢。

3 个答案:

答案 0 :(得分:2)

如果不是重定向,请执行render :action => "discussions/show"。我打算说你必须设置@discussion变量,但这应该完成,因为回复是讨论中的嵌套资源,对吗?

答案 1 :(得分:2)

我会将回复存储在flash中,而不是会话,这有助于在操作中传递消息/对象。

如果答案无效并且重定向,控制器只会将答复存储在闪存中:

if @reply.save
   ...
else
   flash[:reply] = @reply
end

你在讨论/展示页面上的表单逻辑需要更聪明一点,并在flash或新的(我假设你在讨论/ show动作中创建)中获取回复:

form_for(flash[:reply] || @reply) do
  ...
end

答案 2 :(得分:0)

我会说你做这件事的方式是合理的。不是最干净的,但它是RESTful。

Radar的建议很棒但是在当前版本的Rails中,使用render :action => "discussions/show"并不能创建正确的行为,至少在我的尝试中,没有嵌套资源路由。使用render :controller => "discussions", :action => "show"会产生另一种不是海报正在寻找的行为。