2017-10-26 4 views
0

私はレールで作業しています5 /監査済み4.6.5 一度に2000個以上のアイテムをバッチ処理しています。 これを使用可能にするには、updatre_all関数を使用する必要があります。監査されたレールはバッチで作成します

Followup.where(id: ids).in_batches(of: 500) do |group| 
    #quick update for user responsiveness 
    group.update_all(step_id: 1) 
    group.delay.newAudits(step_id: 1) 
end 

しかし、監査済み宝石は、そのための基本的なものであることが見えます:

その後、私は私は何をしたいのはそのようなものである1時間に

を必要と被監査を作成したいです。

答えて

0

、私が作成し、管理します最適化されたクエリ 私はAditBatchクラスに入れても遅延

class AuditBatch 


############################################ 
## Init a batch update from a list of ids 
## the aim is to avoid instantiations in controllers 
## @param string class name (eq: 'Followup') 
## @param int[] ids of object to update 
## @param changet hash of changes {key1: newval, key2: newval} 
############################################ 

def self.init_batch_creation(auditable_type, auditable_ids, changes) 
    obj = Object.const_get(auditable_type) 
    group = obj.where(id: auditable_ids) 
    AuditBatch.delay.batch_creation(group, changes, false) 
end 

############################################ 
## insert a long list of audits in one time 
## @param group array array of auditable objects 
## @param changet hash of changes {key1: newval, key2: newval} 
############################################ 
def self.batch_creation(group, changes, delayed = true) 

    sql = 'INSERT INTO audits ("action", "audited_changes", "auditable_id", "auditable_type", "created_at", "version", "request_uuid") 
    VALUES ' 

    total = group.size 
    group.each_with_index do |g, index| 

    parameters = 'json_build_object(' 
    length = changes.size 
    i=1 
    changes.each do |key, val| 
     parameters += "'#{key}'," 
     parameters += "json_build_array(" 
     parameters += "(SELECT ((audited_changes -> '#{key}')::json->>1) FROM audits WHERE auditable_id = #{g.id} order by id desc limit 1)," 
     parameters += val.is_a?(String) ? "'#{val.to_s}'" : val.to_s 
     parameters += ')' 
     parameters += ',' if i < length 
     i +=1 
    end 
    parameters += ')' 

    sql += "('update', #{parameters}, #{g.id}, '#{g.class.name}', '#{Time.now}', (SELECT max(version) FROM audits where auditable_id= #{g.id})+1, '#{SecureRandom.uuid}')" 
    sql += ", " if (index+1) < total 
    end 
    if delayed==true 
    AuditBatch.delay.execute_delayed_sql(sql) 
    else 
    ActiveRecord::Base.connection.execute(sql) 
end 

end 

def self.execute_delayed_sql(sql) 
    ActiveRecord::Base.connection.execute(sql) 
end 
end 
0

group.update_allでコールバックがスキップされ、新しい監査の変更が記録されることはありません。

これらのレコードの監査を手動で作成することはできません。手動で監査の変更を作成することもできますが、「変更されたもの」という参照が必要です。 (audited_changesに入る)。しかし、update_allgroupにした場合、これらの変更は既に失われています。また、このaudited問題に記載されて

(`action`, `audited_changes`, `auditable_id`, `auditable_type`, `created_at`, `version`, `request_uuid`) 

からhttps://github.com/collectiveidea/audited/issues/352

paper_trail、change_logsを保持し、別な宝石も、この問題があります:反復の多くの後https://github.com/airblade/paper_trail/issues/337

+0

を追加するには、あなたのためのお手伝いをお願いいたします。 私が探しているのは、creatメソッド(多分インスタンスとchages)の引数をとる方法です – Jaycreation

関連する問題