繁体   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