Ruby on rails Rails:在XHR中重定向

Ruby on rails Rails:在XHR中重定向,ruby-on-rails,Ruby On Rails,我有一个家长模型,它有孩子。如果某个父项的所有子项都被删除,我想也自动删除父项 在非AJAX场景中,在ChildrenController中,我将执行以下操作: @parent = @child.parent @child.destroy if @parent.children.empty? redirect_to :action => :destroy, :controller => :parents, :

我有一个
家长
模型,它有
孩子
。如果某个
父项的所有
子项
都被删除,我想也自动删除
父项

在非AJAX场景中,在
ChildrenController
中,我将执行以下操作:

@parent = @child.parent
@child.destroy
if @parent.children.empty?
    redirect_to :action => :destroy, 
                :controller => :parents, 
                :id => @parent.id
end
但当请求是XHR时,这是不可能的。重定向导致GET请求

使用AJAX实现这一点的唯一方法是向响应RJS添加逻辑,使其创建一个
link\u to\u remote
元素,“单击”它,然后删除它。看起来很难看。有更好的办法吗

澄清


当我使用术语重定向时,我不是指HTTP重定向。我的意思是,我不想返回与销毁
子项相关的RJ,而是想在
父项上执行
销毁
,并返回与销毁父项相关的RJ。

我想您可以在RJ中设置
窗口.location.href
,类似于

<% if @parent.children.empty? %>
  window.location.href='<%= url_for :action => :destroy, 
                                   :controller => :parents, 
                                   :id => @parent.id %>'
<% else %>
  .. do your normall stuff here ..
<% end %>

我会听nathanvda说什么,但您可以通过ruby语法来实现(rjs中不需要erb scriptlet):


通过重定向销毁父级的更好方法是在after_钩子中进行。你不仅不需要告诉你的用户的浏览器发出另一个请求,你也不需要跟踪代码中删除孩子的地方,这样你就不会被绞死

class Parent < ActiveRecord::Base

  # also worth getting the dependent destroy, so you don't have hanging children
  has_many :chilren, :dependent => :destroy 

end

class Child < ActiveRecord::Base

  after_destroy { parent.destroy  if parent.children.empty? }

end
类父级:毁灭
结束
类Child

然后,您可以按照自己喜欢的方式处理发生这种情况时向用户显示的内容,例如将用户重定向到“/parents”。

我希望通过XHR调用parent destroy操作。此解决方案是URL重定向。您不能在XHR控制器操作中执行重定向,但可以呈现一个RJS,该RJS将为您执行重定向。我以为那是你的问题?控制器操作需要执行删除操作,如果没有更多项:重定向。没有?也许我误用了重定向这个词。我希望响应RJS与销毁父级相关。i、 e.从
ChildrenController
的销毁,我想转到
ParentsController
的销毁,跳过
ChildrenController
的响应。因此,在该过程的任何阶段都不应发出HTTP重定向。而不是渲染,然后只需调用
ParentsController.new.destroy
。您可能需要正确设置
参数。但这应该行得通。但不是说漂亮。另一种方法是将类似的功能提取到一个单独的函数中,将其放在一个模块中,并将其包括在内。这将调用父模型
destroy
操作。我希望ParentsController
销毁
,以便返回的RJ将是已删除的父级RJ,而不是已删除的子级RJ。原因是我想从页面中删除整个父div。这将包括子级,所以我不需要调用子RJ。是的,但是“业务逻辑”不应该属于您的控制器,它应该属于您的模型。如果在你的应用程序中没有“没有孩子的父母”的功能,那么它应该是你模型中的一个钩子,以防止你必须在应用程序中可以删除孩子的每个部分都实现这一功能。然后,您的控制器可以只呈现一个rjs,该rjs检查父节点是否存在,并相应地返回对div的删除。请参阅我对@nathanvda的评论。
if @parent.children.empty?
  page.redirect_to(url_for :action => :destroy, 
                           :controller => :parents, 
                           :id => @parent.id)
else
  .. do your normall stuff here ..
end
class Parent < ActiveRecord::Base

  # also worth getting the dependent destroy, so you don't have hanging children
  has_many :chilren, :dependent => :destroy 

end

class Child < ActiveRecord::Base

  after_destroy { parent.destroy  if parent.children.empty? }

end