Jeroen van Baarsen

Disclaimer: Este post é principalmente um lembrete para mim, então eu não tenho que Google-lo todas as vezes.

no meu dayjob às vezes tenho que copiar registros de banco de dados,sei que o rails tem pelo menos 2 (Se você souber mais, por favor me avise!) métodos integrados de fazê-lo, mas um faz issoligeiramente diferente do outro. Os dois métodos de que estou falando são clonee dup.

A fonte do Rails está dizendo o seguinte sobre ambos:

Clone

Idêntico ao Ruby método clone. Esta é uma cópia “superficial”. Esteja avisado de que seus atributos não são copiados.Isso significa que modificar atributos do clone modificará o original, uma vez que ambos apontarão para os mesmos atributos hash. Se você precisar de uma cópia de seu hash de atributos, use o método # dup.

Dup

objetos enganados não têm ID atribuído e são tratados como novos registros. Notoque esta é uma cópia “superficial”, pois copia os atributos do objeto apenas, NÃO suas associações. A extensão de uma cópia” profunda ” é aplicaçãoespecífica e, portanto, é deixada para o aplicativo implementar de acordo com sua necessidade.O método dup não preserva os carimbos de data|hora (criado|atualizado)_(at / on).

Ok, isso é claro. Mas o que isso significa exatamente na prática? Vamos criar um exemplo de código:

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>

Como você pode ver, quando você clone DB objeto, ele mantém todos os seus dados, mesmo que o id, e quando você usar dup seus cria um novo objeto, com os dados do objecto antigo. O id e createdat e updatedat estão vazios!

Vamos dar o exemplo de código acima um pouco mais, o que happends se nós alteração de dados

Primeiro o 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">

Como você pode ver, quando eu mudar p2 dados p1 também é alterado. Isso ocorre porque clone cria apenas uma cópia superficial.

agora vamos dar uma olhada 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>

o objeto p3 é afetado apenas por nossa alteração, isso ocorre porque é um novo objeto, se você perguntar persisted?, ele retornará false, uma vez que ainda não está armazenado no banco de dados. Portanto, se quisermos salvar p3, precisamos ligar para save.

isso também significa que, se eu usar clone, os objetos são exatamente os mesmos? Vamos dar uma olhada!

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

portanto, podemos concluir que o método clone faz uma cópia superficial e dup cria um novo objeto. Uma pequena nota lateral, dup não copia associações

Deixe uma resposta

O seu endereço de email não será publicado.