¿Cuál es la forma más sencilla de duplicar un registro activo?

Resuelto Brent asked hace 16 años • 12 respuestas

Quiero hacer una copia de un objeto ActiveRecord, cambiando un solo campo en el proceso (además del id ). ¿Cuál es la forma más sencilla de lograr esto?

Me doy cuenta de que podría crear un nuevo registro y luego iterar sobre cada uno de los campos copiando los datos campo por campo, pero pensé que debía haber una manera más sencilla de hacerlo.

Quizás algo como esto:

 new_record = Record.copy(:id)
Brent avatar Sep 13 '08 04:09 Brent
Aceptado

Para obtener una copia, utilice el método dup (o clonar para <rails 3.1+):

#rails >= 3.1
new_record = old_record.dup

# rails < 3.1
new_record = old_record.clone

Luego puedes cambiar los campos que quieras.

ActiveRecord anula el clon de Objeto# integrado para brindarle un registro nuevo (no guardado en la base de datos) con una ID no asignada.
Tenga en cuenta que no copia asociaciones, por lo que tendrá que hacerlo manualmente si es necesario.

El clon de Rails 3.1 es una copia superficial, use dup en su lugar...

Michael Sepcot avatar Sep 12 '2008 21:09 Michael Sepcot

Dependiendo de sus necesidades y estilo de programación, también puede usar una combinación del nuevo método de la clase y fusionar. A falta de un ejemplo mejor y simple , supongamos que tiene una tarea programada para una fecha determinada y desea duplicarla en otra fecha. Los atributos reales de la tarea no son importantes, por lo tanto:

old_task = Tarea.find(task_id)
new_task = Task.new(old_task.attributes.merge({:scheduled_on => some_new_date}))

creará una nueva tarea con :id => nil, :scheduled_on => some_new_datey todos los demás atributos iguales que la tarea original. Al utilizar Task.new, tendrá que llamar explícitamente a guardar, por lo que si desea que se guarde automáticamente, cambie Task.new a Task.create.

Paz.

Phillip Koebbe avatar Sep 15 '2008 13:09 Phillip Koebbe

También te puede gustar la gema Amoeba para ActiveRecord 3.2.

En tu caso, probablemente quieras hacer uso de las opciones nullify, regexo prefixdisponibles en la configuración DSL.

Admite la duplicación recursiva fácil y automática de archivos has_oney asociaciones, preprocesamiento de campos y una configuración has_manyDSL has_and_belongs_to_manypotente y altamente flexible que se puede aplicar tanto al modelo como sobre la marcha.

asegúrese de consultar la documentación de Amoeba , pero su uso es bastante sencillo...

justo

gem install amoeba

o agregar

gem 'amoeba'

a tu archivo de gemas

luego agregue el bloque de ameba a su modelo y ejecute el dupmétodo como de costumbre

class Post < ActiveRecord::Base
  has_many :comments
  has_and_belongs_to_many :tags

  amoeba do
    enable
  end
end

class Comment < ActiveRecord::Base
  belongs_to :post
end

class Tag < ActiveRecord::Base
  has_and_belongs_to_many :posts
end

class PostsController < ActionController
  def some_method
    my_post = Post.find(params[:id])
    new_post = my_post.dup
    new_post.save
  end
end

También puede controlar qué campos se copian de numerosas maneras, pero, por ejemplo, si desea evitar que se dupliquen los comentarios pero desea mantener las mismas etiquetas, puede hacer algo como esto:

class Post < ActiveRecord::Base
  has_many :comments
  has_and_belongs_to_many :tags

  amoeba do
    exclude_field :comments
  end
end

También puede preprocesar campos para ayudar a indicar la unicidad tanto con prefijos como con sufijos, así como con expresiones regulares. Además, también existen numerosas opciones para que puedas escribir en el estilo más legible para tu propósito:

class Post < ActiveRecord::Base
  has_many :comments
  has_and_belongs_to_many :tags

  amoeba do
    include_field :tags
    prepend :title => "Copy of "
    append :contents => " (copied version)"
    regex :contents => {:replace => /dog/, :with => "cat"}
  end
end

La copia recursiva de asociaciones es fácil, simplemente habilite la ameba también en los modelos infantiles.

class Post < ActiveRecord::Base
  has_many :comments

  amoeba do
    enable
  end
end

class Comment < ActiveRecord::Base
  belongs_to :post
  has_many :ratings

  amoeba do
    enable
  end
end

class Rating < ActiveRecord::Base
  belongs_to :comment
end

La configuración DSL tiene aún más opciones, así que asegúrese de consultar la documentación.

¡Disfrutar! :)

Vaughn Draughon avatar Feb 28 '2012 16:02 Vaughn Draughon

Utilice ActiveRecord::Base#dup si no desea copiar la identificación

bradgonesurfing avatar Aug 05 '2011 13:08 bradgonesurfing