Kiel fari ŝanĝojn al modelo ope
Kelkfoje ni volas fari arajn operaciojn por modelon en Rails. La unua ebleco estas uzi simplan iteracion kaj po unu post unu fari la operacio, sed foje tio povas esti kosteme efikece. ActiveRecord
donas al ni multaj eblecoj fari simplan agon al la tuta datumaro kaj foje eĉ pli rapide, sed kun iom da flankkazoj. Sube mi klarigas ilin.
Legado
Vi povas peti por ĉiu rikordo el la datumbazo kaj fari ion kun ĝi per Modelo.all.each { |a| a.funkcio }
sed kio okazas se vi havas 1,000,000 Modeloj. Ĝi ŝarĝas ĉion en memoron, kiu verŝajne ne estas kion vi volas. Por helpi en ĉi tiu kazo ActiveRecord havas find_each
. find_each
liveras ĉiun rikordon sed ope (antaŭagordita al milope). Ekzemple:
Modelo.find_each { |a| a.funkcio }
Iteracias la tutan sed nur ŝarĝas memoren milope.
Modelo.where(aktiva: true).find_each { |a| a.funkcio }
Iteracias nur ties kies aktivo estas vera kaj ŝarĝas milope.
Modelo.find_each(batch_size: 100) { |a| a.funkcio }
Iteracias la tutan sed nur ŝarĝas memoren centope.
Ŝanĝado
Ni diru ke ni havas aro de Artikolo
kiuj estas ActiveRecord::Base
objektoj kaj ni volas tuj publikigi ĉiujn. Ni havas du eblecojn, la unua estas vidu ĉiujn kaj ŝanĝi ilin unuope.
Artikolo.each do |artikolo|
artikolo.update_attribute!(:aktiva, true)
end
kiel en la legado sekcio supren por ne ŝarĝe ĉion memoren
Artikolo.find_each do |artikolo|
artikolo.update_attribute!(:aktiva, true)
end
La avantaĝo estas ke ĝi plenumos la referencovokatajn funkciojn definita en la modelo, do se vi havis after_save
funkcion ĝi vokiĝu.
Se vi ne bezonas la referencovokatajn funkciojn vi povas uzi update_column
. Ĝi ŝanĝos la datumbazon ne per ActiveRecord sed per SQL update
komando. Do ĝi kontrolos nek la datumkontrolojn nek la referencovokatajn funkciojn sed ĝi estas multe pli rapida ĉar ĝi estas unu datumbaza komando kaj ne bezonas ŝarĝi la objektojn en memoron.
Artikolo.all.update_column(:aktiva, true)
Aŭ se vi nur volas ŝanĝi subaro de la datumon, vi povas aldoni where
frazon.
Artikolo.where(videbla: 'neto').update_column(:aktiva, true)
Forigado
Kiel por la ŝanĝado ni havas du eblecojn por forigado aŭ kun referencovokataj funkcioj aŭ sen ili. destroy_all
forigos la dependajn modelojn kaj vokos la referencovokatojn funkciojn. Alie delete_all
sendos komandon delete
al la datumbazon kiu eble ne bonas se vi utiligas datumintegrecon.
Ŝarĝas ĉion en memoro kaj forigos dependajn modelojn:
Artikolo.destroy_all
Artikolo.where(aktiva: true).destroy_all
Samas kiel delete from artikoloj;
sendita al la datumbazo:
Artikolo.delete_all
Aldone
Ĉiuj ĉi metodoj (legado, ŝanĝado, forigiado) ankaŭ funkcias kun asociaĵojn.
Se ni havas Libron
n kun multoj Ĉapitro
jn ni povas fari:
la_fundamento = Libro.where(name: "La Fundamento").first
la_fundamento.ĉapitroj.destroy_all
aŭ
la_fundamento.ĉapitroj.find_each { |ĉ| ĉ.update_attribute(:aktiva, true) }
Fino
La ope metodoj similas al la map
kaj each
funkcioj de la Enumerable
modulo sed por ActiveRecord::Base
-ajn modelojn. Do venontfoje kiam vi bezonas fari ion al ĉiu modela aĵo, espereble ĉi artikolo povas helpi vin.