2010-08-19 77 views
0

我有一個Parent模型,它有Children。如果刪除了某個Parent的所有Children,我也想自動刪除ParentRails:在XHR內重定向

在非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_to_remote元素,「點擊」它,然後刪除它。看起來很醜陋。有沒有更好的辦法?

澄清

當我使用術語重定向,我的意思不是HTTP重定向。我的意思是,不是返回與銷燬Child相關聯的RJS,我想在Parent上執行destroy,並返回與銷燬Parent相關聯的RJS。

回答

0

我想你可以在你的RJS設置window.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 %> 

假設你呈現JavaScript。不知道它是否完全正確,但希望你明白。

[編輯:添加控制器代碼]

使其更清晰,您的控制器將如下所示

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

我想通過XHR調用父消滅行爲。該解決方案是一個URL重定向。 – shmichael 2010-08-21 06:52:18

+0

您不能在XHR控制器操作中執行重定向,但您可以呈現將爲您執行重定向的RJS。我以爲這是你的問題?您的控制器操作需要執行刪除操作,如果沒有更多項目:重定向。沒有? – nathanvda 2010-08-21 20:05:14

+0

也許我誤用了術語重定向。 我想回應RJS是與銷燬'父'關聯的一個。即從'ChildrenController'的銷燬我想移動到'ParentsController'的銷燬,完全跳過'ChildrenController'的響應。 因此,在進程的任何階段都不應該發佈HTTP重定向。 – shmichael 2010-08-22 07:20:20

1

我會聽nathanvda說什麼,但是你可以通過紅寶石語法做到這一點(而你並不需要在RJS ERB小腳本):

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

查看我對@nathanvda的評論。 – shmichael 2010-08-21 06:56:53

1

通過重定向破壞父更好的辦法是做在after_hook。不僅您不必告訴用戶的瀏覽器再發出一個請求,您也不需要跟蹤代碼中刪除孩子的任何地方,這樣您就不會終止與父母的關係。

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 

然後,你可以處理不過你喜歡什麼向用戶展示這種情況發生時,如用戶重定向到「/父母。

+0

這會調用Parent * model *'destroy'動作。我想要ParentsController'destroy',以便返回的RJS將是已刪除的Parent而不是已刪除的Child。原因是我想從頁面中刪除整個Parent div。這將包括其中的Child,所以我不需要調用Child RJS。 – shmichael 2010-08-21 06:54:02

+0

是的,但'業務邏輯'不應該屬於你的控制器,它應該屬於你的模型。如果您的應用中沒有「沒有孩子的父母」的使用,那麼它應該是模型中的鉤子,以防止您必須在可以刪除子項的應用的每個部分中實現此功能。然後你的控制器可以呈現一個rjs來檢查父項的存在,並相應地返回div的移除。 – 2010-08-25 02:11:34