2013-11-24 39 views
0

我在我的會員控制器下面的代碼:軌道4 - 更新前刪除另一個表中的行

def update 
    @member.phone_numbers.destroy_all 
    respond_to do |format| 
    if @member.update(member_params) 
     format.html { redirect_to @member, notice: 'Member was successfully updated' } 
    else 
     format.html { render action: 'edit' } 
    end 
    end 
end 

我必須更新成員之前,從PHONE_NUMBERS刪除現有的記錄,因爲電話號碼必須再次插入(由於可能的訂單更改和其他原因,但沒關係)。

現在的問題是:它的工作原理,但如果成員未能更新,所有的電話號碼將被刪除。

如果@ member.update失敗,可以採取什麼措施來避免此問題?

回答

1

裹到這個包裹該語句放入交易,並從控制器調用一個輔助方法:

# Member Model 
def delete_phone_numbers_and_update(params) 
    Member.transaction do 
    phone_numbers.destroy_all 
    update(params) 
    end 
end 

# Controller 
def update 
    respond_to do |format| 
    if @member.delete_phone_numbers_and_update(member_params) 
     format.html { redirect_to @member, notice: 'Member was successfully updated' } 
    else 
     format.html { render action: 'edit' } 
    end 
    end 
end 
+0

它工作完美。非常感謝你! – stefanobaldo

+1

小修改:使用_Member.transaction do_而不是_Member.transaction.do_ – stefanobaldo

+0

編輯修正錯字和歡呼聲。 –

2

您可能會考慮標記要銷燬的電話號碼,而不是實際刪除它們。

@member.phone_numbers.map(&:mark_for_destruction) 

然後,當您執行@ member.update時,它應該一次更新和銷燬關聯的電話號碼。以下是#mark_for_destruction的API:http://api.rubyonrails.org/classes/ActiveRecord/AutosaveAssociation.html#method-i-mark_for_destruction

否則,您可以考慮設置事務塊。該API解釋了這個不夠好:http://api.rubyonrails.org/classes/ActiveRecord/Transactions/ClassMethods.html

+0

第一種方法沒有工作,我不能標記**@members.phone_numbers**用於銷燬,因爲這是我必須保存到數據庫的當前值。第二種方法(交易塊)完美運作。謝謝。 – stefanobaldo