Disclaimer: Questo post è principalmente un promemoria per me stesso, quindi non devo Google ogni volta.
Al mio dayjob a volte devo copiare i record del database, so che rails ha almeno 2 (se ne sai di più, per favore fammelo sapere!) metodi integrati per farlo, ma uno lo faleggermente diverso dall’altro. I due metodi di cui sto parlando sono clone
e dup
.
La fonte di Rails sta dicendo quanto segue su entrambi:
Clone
Identico al metodo clone di Ruby. Questa è una copia “superficiale”. Tieni presente che i tuoi attributi non vengono copiati.Ciò significa che la modifica degli attributi del clone modificherà l’originale, poiché entrambi punteranno allo stesso hash degli attributi. Se hai bisogno di una copia del tuo hash degli attributi, usa il metodo #dup.
Dup
Gli oggetti duplicati non hanno id assegnati e vengono trattati come nuovi record. Nota che questa è una copia “superficiale” in quanto copia solo gli attributi dell’oggetto, non le sue associazioni. L’estensione di una copia “profonda” è applicationspecific ed è quindi lasciata all’applicazione da implementare in base alle sue necessità.Il metodo dup non conserva i timestamp (creati / aggiornati)_(at / on).
Ok, questo è chiaro. Ma cosa significa esattamente in pratica? Consente di creare un esempio di codice:
p1 = Post.create(title: 'Post 1', message: 'Amazing message')=> #<Post id: 1, title: "Post 1", message: "Amazing message", created_at: "2014-07-01 19:45:44", updated_at: "2014-07-01 19:45:44">p2 = p1.clone=> #<Post id: 1, title: "Post 1", message: "Amazing message", created_at: "2014-07-01 19:45:44", updated_at: "2014-07-01 19:45:44">p3 = p1.dup=> #<Post id: nil, title: "Post 1", message: "Amazing message", created_at: nil, updated_at: nil>
Come puoi vedere, quando si clone
un oggetto DB, mantiene tutti i suoi dati, anche l’id, e quando si utilizza dup
crea un nuovo oggetto, con i dati del vecchio oggetto. L’id e createdat e updatedat sono però vuoti!
Prendiamo l’esempio di codice sopra un po ‘ più avanti, cosa succede se cambiamo i dati
Prima il Clone
p1 = Post.create(title: 'Post 1', message: 'Amazing message')p2 = p1.clonep2.title = "This is now p2"p1 #=> #<Post id: 1, title: "This is now P2", message: "Amazing message", created_at: "2014-07-01 19:45:44", updated_at: "2014-07-01 19:45:44">p2 #=> #<Post id: 1, title: "This is now P2", message: "Amazing message", created_at: "2014-07-01 19:45:44", updated_at: "2014-07-01 19:45:44">
Come puoi vedere, quando cambio p2
anche i dati in p1
vengono modificati. Questo perché clone
crea solo una copia superficiale.
Ora diamo un’occhiata a Dup
p1 = Post.create(title: 'Post 1', message: 'Amazing message')p3 = p1.clonep3.title = "This is now p3"p1 #=> #<Post id: 1, title: "Post 1", message: "Amazing message", created_at: "2014-07-01 19:45:44", updated_at: "2014-07-01 19:45:44">p3 #=> #<Post id: nil, title: "This is now P3", message: "Amazing message", created_at: nil, updated_at: nil>
L’oggetto p3
è interessato solo dalla nostra modifica, questo perché è un nuovo oggetto, se chiedi persisted?
, restituirà false
, poiché non è ancora memorizzato nel database. Quindi se vogliamo salvare p3
dobbiamo chiamare save
.
Questo significa anche che se uso clone
che gli oggetti sono esattamente gli stessi? Consente di controllare fuori!
p1 = Post.create(title: 'Post 1', message: 'Amazing message')p2 = p1.clonep3 = p1.dupp2 == p1 #=> truep3 == p1 #=> false
Quindi possiamo concludere che il metodo clone
crea una copia superficiale e dup
crea un nuovo oggetto. Una piccola nota a margine, dup
non copia le associazioni