开发者

Rails: Redirect within XHR

开发者 https://www.devze.com 2023-01-12 11:19 出处:网络
I have a 开发者_如何学JAVAParent model which has Children. If all the Children of a certain Parent are deleted, I\'d like to automatically delete the Parent as well.

I have a 开发者_如何学JAVAParent model which has Children. If all the Children of a certain Parent are deleted, I'd like to automatically delete the Parent as well.

In a non-AJAX scenario, in the ChildrenController I would do:

@parent = @child.parent
@child.destroy
if @parent.children.empty?
    redirect_to :action => :destroy, 
                :controller => :parents, 
                :id => @parent.id
end

But this is impossible when the request is XHR. The redirect causes a GET request.

The only way I can think of to do this with AJAX is add logic to the response RJS, causing it to create a link_to_remote element, "click" it, and then remove it. It seems ugly. Is there a better way?

Clarification

When I use the term redirect, I do not mean an HTTP redirect. What I mean is that instead of returning the RJS associated with destroying Child, I want to perform destroy on Parent and return the RJS associated with destroying Parent.


I would listen to what nathanvda says, but you can do it via ruby syntax (and you don't need erb scriptlets in rjs):

if @parent.children.empty?
  page.redirect_to(url_for :action => :destroy, 
                           :controller => :parents, 
                           :id => @parent.id)
else
  .. do your normall stuff here ..
end


A better approach to destroying the parent through a redirect is doing it in an after_hook. Not only you don't have to tell your user's browser to make another request, you also don't need to keep track of everywhere in the code where you delete children so you don't end up with hanging parents.

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

Then you can just handle however you prefer what to show the user when that happens, like redirecting the user to '/parents'.


I would guess you could set the window.location.href in your rjs, something like

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

assuming you render javascript. Not sure if it is completely correct, but hope you get the idea.

[EDIT: added controller code]

TO make it clearer, your controller would look as follows

@parent = @child.parent
@child.destroy
if @parent.children.empty?
   render :redirect
end
0

精彩评论

暂无评论...
验证码 换一张
取 消