2010-11-21 16 views
7

我需要一次性刪除大量記錄,並且需要根據另一個與「belongs_to」關係相關的模型中的條件來執行此操作。我知道我可以通過每次檢查條件來進行循環,但是這對於我的大型記錄集來說是永久的,因爲對於每個「belongs_to」它都會進行單獨的查詢。是否有可能delete_all與內部連接條件?

下面是一個例子。我有一個「產品」模型,「屬於」一個「藝術家」,並可以說藝術家有一個屬性「is_disabled」。

如果我想刪除屬於殘疾人藝術家的所有產品,我希望能夠做這樣的事情:

Product.delete_all(:joins => :artist, :conditions => ["artists.is_disabled = ?", true]) 

這可能嗎?我之前已經直接在SQL中完成了這項工作,但不確定是否可以通過rails來完成。

回答

4

問題是delete_all放棄了所有的連接信息(以及正確的)。你想要做的就是把它作爲內部選擇。

如果您使用的Rails 3,您可以創建一個範圍,這將使你想要的東西:

class Product < ActiveRecord::Base 
    scope :with_disabled_artist, lambda { 
    where("product_id IN (#{select("product_id").joins(:artist).where("artist.is_disabled = TRUE").to_sql})") 
    } 
end 

您查詢通話則變爲

Product.with_disabled_artist.delete_all 

您也可以使用相同的查詢內聯,但這不是很優雅(或自我記錄):

Product.where("product_id IN (#{Product.select("product_id").joins(:artist).where("artist.is_disabled = TRUE").to_sql})").delete_all 
+2

它是如何 「理當如此」 刪除連接?通常需要加入條件才能限制要刪除的記錄。我認爲最糟糕的部分是它的默默無聞,這可能是相當令人驚訝的。 – 2014-09-18 21:55:10

+0

我只是說你無法做一個連接刪除所有像SQL一樣的東西,因此正確的如此。我很確定Rails的後續版本總是進行子查詢。不確定這是最好的方法,因爲它使它看起來是聯接中的下層查詢,因爲它確實是一個子查詢。 – gcastro 2014-11-09 20:32:59

+1

@gcastro這是不真實的 - 在MySQL中至少有一個可以絕對使用連接語句執行刪除。 http://dev.mysql.com/doc/refman/5.7/en/delete.html – bluefear 2016-10-27 00:29:49

0

如果您使用的是Rails 2 y你不能做到以上。另一種方法是在find方法中使用連接子句,並在每個項目上調用delete。

TellerLocationWidget.find(:all, :joins => [:widget, :teller_location], 
     :conditions => {:widgets => {:alt_id => params['alt_id']}, 
     :retailer_locations => {:id => @teller_location.id}}).each do |loc| 
     loc.delete 
    end 
+0

這將導致個別刪除不一樣,也不會縮放。你應該能夠在Rails 2中使用命名的作用域。 – gcastro 2014-11-09 20:36:53

1

在Rails 4(我在4.2測試),你幾乎可以做OP原本想怎樣

Application.joins(:vacancy).where(vacancies: {status: 'draft'}).delete_all 

會給

DELETE FROM `applications` WHERE `applications`.`id` IN (SELECT id FROM (SELECT `applications`.`id` FROM `applications` INNER JOIN `vacancies` ON `vacancies`.`id` = `applications`.`vacancy_id` WHERE `vacancies`.`status` = 'draft') __active_record_temp) 
+0

雖然這在PostgreSQL上很好,但它在MySQL服務器上速度很慢。謹防。 – lzap 2017-04-03 12:15:30

相關問題