Ruby on rails ActiveRecord事务,节省1000+;条目

Ruby on rails ActiveRecord事务,节省1000+;条目,ruby-on-rails,activerecord,transactions,Ruby On Rails,Activerecord,Transactions,我让EventsController创建如下操作: class EventsController < ApplicationController def create @event = Event.new(params[:event].slice(*Event.accessible_attributes)) if @event.save DraftBuilder.new(event: @event).build(params[:event][:file].

我让EventsController创建如下操作:

class EventsController < ApplicationController

  def create
    @event = Event.new(params[:event].slice(*Event.accessible_attributes))
    if @event.save
      DraftBuilder.new(event: @event).build(params[:event][:file].path) 
      redirect_to @event
    else
      render :new
    end
  end

end
class DraftBuilder
  def build(file)
    @data = parse(file) #@data is an array of hashes with 1000+ records
    @data.each do |pick_arguments|
      Pick.create(pick_arguments)
    end
  end
end
我找到了解决这个问题的办法。将控制器创建操作包装到ActiveRecord::Base.transaction中:

class EventsController < ApplicationController
  around_filter :transactions_filter, only: [:create]

    def transactions_filter
      ActiveRecord::Base.transaction do
        yield
      end
    end
end        
类事件控制器

此解决方案工作时,只创建一个事务,并将整个过程的速度提高约60倍。这是解决这个问题的好方法吗??交易肯定不是为此而设计的??从包含超过1000个条目的文件中创建记录的其他选项有哪些?

减缓进程运行速度的最佳解决方案是使用诸如或之类的后台作业。

您有两种方法:

而不是

@data.each do |pick_arguments|
  Pick.create(pick_arguments)
end
  • 交易
     ActiveRecord::Base.transaction do
       @data.each do |pick_arguments|
         Pick.create(pick_arguments)
       end
     end  
    
  • Gem-activerecord导入
    data = []
    @data.each do |pick_arguments|
      data << Pick.new(pick_arguments)
    end
    Pick.import data
    
    data=[]
    @data.each do | pick_参数|
    
    正如他们所说,您可以使用延迟的任务立即回答用户并在后台处理任务,甚至事务也不被认为是进行批量插入的一种方式,这是ActiveRecord中的常见模式。延迟的任务或resque或sidekiq做我需要的事情。我认为您关于将事务块从控制器下推到DraftBuilder对象的建议也值得一提,因为我认为任何人都不需要了解控制器的“猫是如何被剥皮的”,所以+1。。。当我能够:)我想我已经看到一些铁路工人关于延迟工作和sidekiq,我需要检查一下。我需要在events/show.erb.html中添加一些“处理通知”,因为它会立即将_重定向到@event。对吗?