Varning: Det här inlägget är mestadels en påminnelse för mig själv, så jag behöver inte Google det varje gång.
på mitt dagjobb måste jag ibland kopiera databasposter, jag vet att rails har minst 2 (Om du vet mer, snälla låt mig veta!) inbyggda metoder för att göra det, men man gör detnågot annorlunda än den andra. De två metoderna jag pratar om är clone
och dup
.
källan till skenor säger följande om båda:
klon
identisk med Rubys klonmetod. Detta är en” grund ” kopia. Varnas för att dina attribut inte kopieras.Det betyder att modifierande attribut för klonen kommer att ändra originalet, eftersom de båda pekar på samma attribut hash. Om du behöver en kopia av dina attribut hash, använd #dup metoden.
Dup
Duped-objekt har inget ID tilldelat och behandlas som nya poster. Notera att detta är en” grund ” kopia eftersom den kopierar objektets attributendast, inte dess föreningar. Omfattningen av en” djup ” kopia är applikationsspecifik och lämnas därför till ansökan för att genomföra enligt dess behov.DUP-metoden bevarar inte tidsstämplarna(skapade|uppdaterade)_(vid|på).
Ok, det är klart. Men vad betyder det exakt i praktiken? Låt oss skapa ett kodexempel:
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
ett DB-objekt, behåller det alla dess data, även id, och när du använder dup
skapar det ett nytt objekt med data från det gamla objektet. Id och createdat och updatedat är dock tomma!
Låt oss ta kodexemplet ovan lite längre, vad händer om vi ändrar 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 jag ändrar p2
ändras också data i p1
. Detta beror på att clone
bara skapar en grund kopia.
nu kan ta en titt 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åverkas bara av vår förändring, det beror på att det är ett nytt objekt, om du frågar persisted?
kommer det att returnera false
, eftersom det ännu inte är lagrat i databasen. Så om vi vill spara p3
måste vi ringa save
.
betyder det också att om jag använder clone
att objekten är exakt samma? Låt oss kolla in det!
p1 = Post.create(title: 'Post 1', message: 'Amazing message')p2 = p1.clonep3 = p1.dupp2 == p1 #=> truep3 == p1 #=> false
så vi kan dra slutsatsen att metoden clone
gör en grund kopia och dup
skapar ett nytt objekt. En liten sidoanteckning, dup
kopierar inte föreningar