Jeroen van Baarsen

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

Lascia un commento

Il tuo indirizzo email non sarà pubblicato.