Quiero hacer una copia de un registro de registro activo, cambiando un solo campo en el proceso (además de la identificación ). ¿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 fácil de hacerlo ...
como:
@newrecord=Record.copy(:id) *perhaps?*
q = p.clone
, y luegop == q
,true
regreso. Por otro lado, si lo usoq = p.dup
,false
vuelvo al compararlos.new?
método no funciona.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 mejor ejemplo simple , suponga que tiene una tarea programada para una fecha determinada y desea duplicarla en otra fecha. Los atributos reales de la tarea no son importantes, así que:
creará una nueva tarea con
:id => nil
,:scheduled_on => some_new_date
y todos los demás atributos iguales a la tarea original. Con Task.new, deberá llamar explícitamente a save, por lo que si desea guardarlo automáticamente, cambie Task.new a Task.create.Paz.
fuente
WARNING: Can't mass-assign protected attributes: id, due_date, created_at, updated_at
devuelvenTambién te puede interesar la gema Amoeba para ActiveRecord 3.2.
En su caso, es probable que desee hacer uso de los
nullify
,regex
oprefix
las opciones disponibles en el DSL configuración.Es compatible con fácil y automática la duplicación recursiva de
has_one
,has_many
yhas_and_belongs_to_many
asociaciones, preprocesamiento de campo y una DSL configuración altamente flexible y potente que se puede aplicar tanto al modelo y sobre la marcha.asegúrese de consultar la documentación de Amoeba, pero el uso es bastante fácil ...
sólo
o agregar
a tu Gemfile
luego agregue el bloque de ameba a su modelo y ejecute el
dup
método como de costumbreTambién puede controlar qué campos se copian de varias maneras, pero, por ejemplo, si desea evitar que los comentarios se dupliquen pero desea mantener las mismas etiquetas, puede hacer algo como esto:
También puede preprocesar campos para ayudar a indicar unicidad con prefijos y sufijos, así como expresiones regulares. Además, también hay numerosas opciones para que pueda escribir en el estilo más legible para su propósito:
La copia recursiva de asociaciones es fácil, solo habilite ameba en modelos secundarios también
La configuración DSL tiene aún más opciones, así que asegúrese de consultar la documentación.
¡Disfrutar! :)
fuente
.amoeba_dup
, no solo.dup
. Estaba tratando de ejecutar este código, pero no estaba funcionando aquí.Use ActiveRecord :: Base # dup si no desea copiar la identificación
fuente
.clone
Usualmente solo copio los atributos, cambiando lo que sea que necesite cambiar:
fuente
unknown attribute
error con una columna debido a una columna que está allí debido a una relación has_many. ¿Hay alguna forma de evitar esto?User.create(old_user.attributes.merge({ login: "newlogin", id: nil }))
. Esto salvará a un nuevo usuario con la identificación única correcta.Si necesita una copia profunda con asociaciones, le recomiendo la gema deep_cloneable .
fuente
En Rails 5 simplemente puede crear objetos duplicados o grabar de esta manera.
fuente
La forma fácil es:
O
fuente
Aquí hay una muestra de cómo anular el
#dup
método ActiveRecord para personalizar la duplicación de instancias e incluir también la duplicación de relaciones:Nota: este método no requiere ninguna gema externa, pero requiere una versión más reciente de ActiveRecord con el
#dup
método implementadofuente
También puedes consultar la gema act_as_inheritable .
"Acts As Inheritable es una gema rubí escrita específicamente para los modelos Rails / ActiveRecord. Está destinada a ser utilizada con la Asociación autorreferencial o con un modelo que tenga un padre que comparta los atributos heredables. Esto le permitirá heredar cualquier atributo o relación del modelo padre ".
Al agregar
acts_as_inheritable
a sus modelos, tendrá acceso a estos métodos:herencia_atributos
heredar_relaciones
Espero que esto le pueda ayudar.
fuente
Como podría haber más lógica, al duplicar un modelo, sugeriría crear una nueva clase, donde maneje toda la lógica necesaria. Para aliviar eso, hay una gema que puede ayudar: payaso
Según sus ejemplos de documentación, para un modelo de Usuario:
Creas tu clase de clonador:
y luego úsalo:
Ejemplo copiado del proyecto, pero le dará una visión clara de lo que puede lograr.
Para un registro rápido y simple, iría con:
Model.new(Model.last.attributes.reject {|k,_v| k.to_s == 'id'}
fuente