这发生在我身上好几次,我还没有找到一个可以接受的解决方案.
我在一个站点的主页中有一个表单,它形成指向另一个控制器的点,该控制器实际上负责处理数据.当表单成功提交后,另一个控制器会通过一条漂亮的flash [:notice]消息将您送回主页,这就是它的结尾.
当存在验证问题时,它就成了问题.我想要做的是显示带有验证错误的表单的主页.通常提到的天真解决方案是你可以渲染另一个模板,但显示主页不仅仅是渲染模板,它还有很多功能.渲染该模板的唯一方法是复制并粘贴此其他控制器操作中的功能,或者可能将所有功能从控制器中移除,这也不是很好
有更好的解决方案吗?
更新:我理解人们说控制器动作应该更小并调用另一种方法,但在实践中,我看不到如何实现它.我将在我做过的网站上发布一个真实的例子.
有两个模型和控制器:帖子和评论.帖子有很多原因.帖子以这种方式显示:
def index
set_posts # sets @posts
end
def show
@post = Post.find_by_slug(params[:id])
@comment = Comment.new
if not @post
flash[:error] = "'#{params[:id]}' does't exist"
set_posts
render :action => :index, :status => :not_found
end
end
private
def set_posts
@posts = Posts.get_all_public_posts
end
注释控制器只有一个创建操作:
def create
@comment = Comment.new(params[:comment])
@comment.post = Post.find_by_slug params['post_id']
if not @comment.post
# Now what?
# We should here call PostsController.set_posts and render views/posts/index
end
if @reason.save
flash[:notice] = 'Thank you for your message.'
redirect_to(@reason.item)
else
# Now what?
# We should here call PostsController.show without overriding the @comment
end
end
结束
“现在怎么样?”零件是我没有很好的解决方案.
最佳答案 在呈现表单并将请求重定向到默认操作时,主页的其余部分会发生多大变化?
如果答案不是很多,那么您应该考虑使用remote_form_for并仅在成功或表单上更新通知区域,并在失败时验证错误.
如果这不符合您的喜好,您可以将主页操作中的所有重复逻辑移动到ApplicationController类中定义的方法,并将其作为主页操作上的before_filter和处理表单的操作的一部分进行调用. N.B:这样做会要求你设置实例变量,过滤器中设置的局部变量在动作之前不会持久存在.