2010/2/18 Marco M. [email protected]:
Ho un task rake che ricicla degli scarti. Mi piacerebbe sapere se è
chiaro e come migliorereste questo codice:
Ciao,
non ho capito cos’è discards; potrebbe essere importante per capire
cosa deve fare il codice.
In realtà non ho capito neanche cosa sia Discard; forse mi faccio
fuorviare dal nome, ma fa niente.
L’unica cosa che credo di aver capito è che in caso di errori nel
lavoro sporco, i record restano invariati.
Immagino che quel discards[i] == nil in realtà sia discards[i] = nil,
perché altrimenti non fa assolutamente niente.
Così, al volo, proporrei:
begin
Fa qualcosa
Discart.transaction do
for i in 0…discards.size
discard = discards[i]
begin
# Lavoro sporco
rescue StandardError => err
discard.update_attributes(:state_id=>State::ERROR,
:description=>err.message)
discards.delete_at i
end
end
if discards.any?
Discard.update_all(“state_id=#{State::COMPLETED}”,
[“id in (?) and state_id = ?”,
discards.map(&:id),
State::RECYCLED])
end
# Fa qualcos’altro
exit 0
end
rescue StandardError => err
puts "Error " << err.message
exit 9
end
Questo perché quel
if defined? i; i+=1; else; i=0; end
non mi piace per niente. Inoltre è sempre bene sanitizzare le
condizioni (vedi la chiamata ad update_all), anche quando le scrivi tu
e sai che non ci sono rischi di injection.
Nota anche che:
Discard.update_all(“state_id=#{State::COMPLETED}”,
[“id in (?) and state_id = ?”,
discards.map(&:id),
State::RECYCLED])
è identico a:
Discard.scoped(:conditions => [“id in (?) and state_id = ?”,
discards.map(&:id),
State::RECYCLED
]).update_all(“state_id=#{State::COMPLETED}”)
per cui si può scegliere quella che sembra più chiara.
Infine, se quei discards sono record (ad esempio, se fai discards =
Discard.all(…)), potresti considerare l’idea di usare find_each, che
riduce i problemi in caso di tanti record.
http://api.rubyonrails.org/classes/ActiveRecord/Batches/ClassMethods.html
Spiegaci meglio il problema, magari ci viene un’idea migliore!
pietro