Jeroen van Baarsen

Zastrzeżenie: ten post jest głównie przypomnieniem dla siebie, więc nie muszę go za każdym razem wygooglować.

w mojej pracy czasami muszę kopiować rekordy bazy danych,wiem, że rails ma co najmniej 2 (jeśli wiesz więcej, daj mi znać!) wbudowane metody robienia tego, ale jeden robi tostopnie inaczej niż drugi. Dwie metody, o których mówię to clone i dup.

źródło Rails mówi o obu:

Klon

identyczny z metodą klonowania Ruby. To jest” płytka ” Kopia. Pamiętaj, że twoje atrybuty nie są kopiowane.Oznacza to, że modyfikowanie atrybutów klonu spowoduje modyfikację oryginału, ponieważ oba będą wskazywać na te same atrybuty hash. Jeśli potrzebujesz kopii skrótu atrybutów, użyj metody # dup .

Dup

Duped obiekty nie mają przypisanego id i są traktowane jako nowe rekordy. Nie jest to” płytka ” Kopia, ponieważ kopiuje tylko atrybuty obiektu, a nie jego skojarzenia. Zakres „głębokiej” kopii jest specyficzny dla aplikacji i dlatego pozostaje w gestii aplikacji w celu wdrożenia zgodnie z jej potrzebami.Metoda dup nie zachowuje znaczników czasu(created|updated)_(at|on).

OK, to jasne. Ale co to dokładnie oznacza w praktyce? Stwórz próbkę kodu:

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>

jak widać, gdy clone obiekt DB, zachowuje wszystkie swoje dane, nawet id, a gdy używasz dup tworzy nowy obiekt, z danymi starego obiektu. Id oraz createdat i updatedat są jednak puste!

weźmy powyższy przykład kodu nieco dalej, co się stanie, jeśli zmienimy dane

najpierw 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">

jak widać, kiedy zmieniam p2 dane w p1 również są zmieniane. Dzieje się tak, ponieważ clone tworzy tylko płytką kopię.

teraz spójrzmy na 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>

obiekt p3 ma wpływ tylko na naszą zmianę, dzieje się tak dlatego, że jest to nowy obiekt, jeśli zapytasz persisted?, zwróci false, ponieważ nie jest jeszcze przechowywany w bazie danych. Więc jeśli chcemy zapisać p3 musimy zadzwonić save.

czy to również oznacza, że jeśli użyję clone, że obiekty są dokładnie takie same? Sprawdźmy to!

p1 = Post.create(title: 'Post 1', message: 'Amazing message')p2 = p1.clonep3 = p1.dupp2 == p1 #=> truep3 == p1 #=> false

możemy więc stwierdzić, że metoda clone wykonuje płytką kopię, a dup tworzy nowy obiekt. Mała uwaga, dup nie kopiuje skojarzeń

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany.