Ansvarsfraskrivelse: Dette indlæg er for det meste en påmindelse for mig selv, så jeg behøver ikke Google det hver gang.
på min dagjob skal jeg nogle gange kopiere databaseposter,jeg ved, at rails har mindst 2 (Hvis du ved mere, så lad mig det vide!) indbyggede metoder til at gøre det, men man gør detlidt anderledes end den anden. De to metoder, jeg taler om, er clone
og dup
.
kilden til skinner siger følgende om begge:
klon
identisk med Rubys klonmetode. Dette er en “lav” kopi. Vær advaret om, at dine attributter ikke kopieres.Det betyder, at modificerende attributter af klonen vil ændre originalen, da de begge vil pege påsamme attributter hash. Hvis du har brug for en kopi af din attribut-hash, skal du bruge #dup-metoden.
Dup
Duped objekter har intet id tildelt og behandles som nye poster. Bemærk, at dette er en” lav ” kopi, da den kopierer objektets attributterkun, ikke dets foreninger. Omfanget af en” dyb ” kopi er applikationsspecifik og overlades derfor til applikationen at implementere i overensstemmelse med dens behov.Dup-metoden bevarer ikke tidsstemplerne(oprettet|opdateret)_(at|on).
okay, det er klart. Men hvad betyder det nøjagtigt i praksis? Lad os oprette en kodeeksempel:
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>
som du kan se, når du clone
et DB-objekt, holder det alle sine data, selv id ‘ et, og når du bruger dup
, opretter det et nyt objekt med dataene fra det gamle objekt. Id og createdat og updatedat er dog tomme!
lad os tage kodeeksemplet ovenfor lidt længere, hvad sker der, hvis vi ændrer data
først 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">
som du kan se, når jeg ændrer p2
, ændres dataene i p1
også. Dette skyldes, at clone
kun opretter en lav kopi.
lad os nu se på 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>
p3
– objektet påvirkes kun af vores ændring, Dette skyldes, at det er et nyt objekt, hvis du spørger persisted?
, vender det tilbage false
, da det endnu ikke er gemt i databasen. Så hvis vi vil gemme p3
, skal vi ringe save
.
betyder det også, at hvis jeg bruger clone
at objekterne er nøjagtigt de samme? Lad os tjekke det ud!
p1 = Post.create(title: 'Post 1', message: 'Amazing message')p2 = p1.clonep3 = p1.dupp2 == p1 #=> truep3 == p1 #=> false
så vi kan konkludere, at clone
– metoden gør en lav kopi, og dup
opretter et nyt objekt. En lille sidebemærkning, dup
kopierer ikke foreninger