簡體   English   中英

更新has_many / belong_to關系中大量關聯對象的行(Rails 4,PostgreSQL 9.4,activeadmin)

[英]Update massive number of rows of associated objects in has_many/belong_to relations (Rails 4, postgresql 9.4, activeadmin)

創建模型交易時,我使用after_create在DealPrize表上創建獎品。

Deal和DealPrize有一個屬於/有很多關系:一個Deal有很多Deal獎品,一個Dealprize屬於Deal。

它的工作原理是這樣的:在我的管理面板(使用activeadmin)上,在Deal中,我有一個“獎品編號”列,並且我使用了after_create,這樣,每次管理員創建新交易時,應用程序都會使用這個award_number列,並在DealPrize表中創建此數量的獎金(插入必要的行=>,經常超過300,000)。

因此,我創建了一個Deal,並且該應用程序自動創建了大量關聯對象(獎品),例如300,000。

問題是我希望兩天后將獎金數從300,000更改為272,000(少獎)或324,000(更多獎)。

如何更新創建的交易,並告訴我的Rails應用更新相關獎勵的數量(刪除一些或添加一些),而又不破壞和重新創建整個Deal對象?

另外,我需要一種快速的方法(就像我用來創建Deal => raw sql和transaction的方法一樣,因為一次創建的行數非常高)。

模態Deals.rb

has_many   :deal_prizes,  dependent: :delete_all

after_create :create_deal_prizes

CONNECTION = ActiveRecord::Base.connection.raw_connection

    def create_deal_prizes
      begin 
        CONNECTION.describe_prepared('yokoatxz')
      rescue PG::InvalidSqlStatementName
        CONNECTION.prepare('yokoatxz', 'INSERT INTO deal_prizes (deal_id,created_at,updated_at,admin_user_id) values ($1, $2, $3, $4)') 
      end

      Deal.transaction do  
        self.prizes_number.times do |i| 
          CONNECTION.exec_prepared('yokoatxz',  [ { value: self.id},
                                                  { value: '2009-01-23 20:21:13' },
                                                  { value: '2009-01-23 20:21:13' },
                                                  { value: self.admin_user_id }
                                                ] )
        end
      end
    end

謝謝您的幫助,Mathieu

好吧,我認為,如果您只想更改deal_prizes的數量,則可以在Deal上使用before_save回調來測試priest_number和prize_number_was之間的差異,並適當地發出insert或delete語句。

我希望刪除后您可以執行以下操作:

deal_prizes.limit(prize_number_was - prize_number).delete_all

...如果您不在乎哪個被刪除。

您可能想在deal_prizes上使用范圍:

def self.deletable
  where(:taken => false)
end

...以應用可以刪除行的條件,然后將其合並到交易關聯中...

has_many :deletable_deal_prizes, -> {merge(DealPrize.deletable)}, :class_name => "DealPrize"

... 所以你可以:

deleteable_deal_prizes.limit(prize_number_was - prize_number).delete_all

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM