使用ruby 1.9.2和rails 3,如何收集activerecord错误以便稍后显示?或者更好的是,暂停提交直到准备好了?

时间:2011-10-11 17:31:46

标签: ruby-on-rails ruby-on-rails-3

在单个操作中,我将多行插入表中。这些行中的一个或多个可能会导致ActiveRecord :: RecordInvalid问题。发生这种情况时,我希望能够退出此特定操作的所有事务,并让用户在继续之前修复数据。这样做的最佳方法是什么?

现在,如果第二行数据失败,第一行数据已经提交到数据库,因此用户不知道是否应该重新加载第一行。我可以告诉用户有多少行成功,他们可以知道只从该部分修复和重新加载,但如果我可以撤消所有内容并让用户在修复数据后重新开始,那对我来说会更好。 / p>

仅供参考,用户最初将CSV文件加载到一个表中,该表包含其csv文件的每一行*列的行,我从该import_table导入。

这是我在控制器中的一个方法:

  def process_import

    @import = ImportTable.find(params[:id])
    @cells = @import.import_cells
    @new_donors = Array.new
    @existing_donors = Array.new
    class_name = 'Donor'          

    klass = ActiveRecord.const_get(class_name) # get access to class

    #loop through rows
    0.upto(@import.row_count - 1) do |row_index|
      donor = {}
      donation = {} 
      record_status = 'new'     
      row = @cells.select { |cell| cell.row_index == row_index }

      #loop through columns
      0.upto(@import.column_count - 1) do |column_index|
        contents = row.select { |cell| cell.column_index == column_index}[0].contents

        case column_index
          when 0 then   record_status = contents
          when 1 then   donor["id"] = contents
          when 2 then   donor["prefix1"] = contents
          when 3 then   donor["first_name1"] = contents
          when 4 then   donor["middle_name1"] = contents
          ...
        end #case
      end #columns

      unless @donor = Donor.find_by_id(donor["id"])
        donor.delete("id")
        @donor = klass.find_or_initialize_by_company_and_prefix1_and_first_name1_and_last_name1_and_address1(donor) 
      end

      @donor.new_record? ? @new_donors.push(@donor) : @existing_donors.push(@donor)    
      @donor.save!

      if !donation["amount"].blank?
        @donation = @donor.donations.build(donation)
        @donation.save!

        end

    end #rows


   @import.processed_date = Time.now
   @import.save

  end

1 个答案:

答案 0 :(得分:1)

我只是让用户重新提交整个数据

在事务中包装导入过程。如果发生错误,您可以通过引发ActiveRecord::Rollback

来退出整个提交
klass.transaction do
  # loop through rows
  # You might want to call @donor.save rather than @donor.save! so that you do not raise errors, yet still have invalid records.

  raise ActiveRecord::Rollback if (@new_donors+@existing_donors).any?{|donor| !donor.valid? }
end