如何用较少的数据库事务创建/更新多个记录(避免循环)?

时间:2019-07-04 03:16:04

标签: ruby-on-rails

我曾经使用

contact_ids = params[:ticket_note][:contact_ids].reject(&:blank?)
contact_ids.each do |contact_id|
  @ticket_note_recipient = TicketNoteRecipient.new
  @ticket_note_recipient.ticket_note_id = @ticket_note.id
  @ticket_note_recipient.account_contact_id = contact_id
  @ticket_note_recipient.save
end

我用于更新

contact_ids = params[:ticket_note][:contact_ids].reject(&:blank?)
  @d_ticket_note_recipients = TicketNoteRecipient.where(:ticket_note_id =>@ticket_note)
  .where.not(:account_contact_id => contact_ids).delete_all

  contact_ids.each do |contact_id|
    @ticket_note_recipient = TicketNoteRecipient.where(:ticket_note_id =>@ticket_note)
    .where.not(:account_contact_id => contact_id).first
    if @ticket_note_recipient.blank?
      @ticket_note_recipient = TicketNoteRecipient.new
      @ticket_note_recipient.ticket_note_id = @ticket_note.id
      @ticket_note_recipient.account_contact_id = contact_id
      @ticket_note_recipient.save
    end
  end

如何用更少的数据库事务来做到这一点?

2 个答案:

答案 0 :(得分:1)

无法使用开箱即用的方式插入/修改多个记录。但是,您可以使用activerecord-import gem来执行此操作。

在创建新对象时,默认情况下,Rails确实会采用数组,例如:

VoteRecord.create(
  [
    { :prospect_id => prospect.id, :state => "OH", :election_type => "GE", :election => "2011-11-08", :party => row[82], :participate => participated(row[82]) },
    { :prospect_id => prospect.id, :state => "OH", :election_type => "PR", :election => "2011-09-13", :party => row[81], :participate => participated(row[81]) }
    ...
  ]
)

但是这仍然会创建n个查询,每个插入一个,因此实现此目的的唯一方法(无需自己编写SQL查询)是使用activerecord-import

答案 1 :(得分:0)

如果您确实在谈论问题中所说的交易较少,那么这就是方法,将其包装在Transaction

ApplicationRecord.transaction do
  contact_ids.each do |contact_id|
     # ...
     @ticket_note_recipient.save
   end
 end
end