rails query left inner includes active ruby-on-rails ruby rails-activerecord

ruby on rails - query - ¿Cuál es la forma más fácil de duplicar un registro de registro de activación?



rails find (10)

A continuación, se muestra un ejemplo de anulación del método #dup ActiveRecord para personalizar la duplicación de instancias e incluir también la duplicación de relaciones:

class Offer < ApplicationRecord has_many :offer_items def dup super.tap do |new_offer| # change title of the new instance new_offer.title = "Copy of #{@offer.title}" # duplicate offer_items as well self.offer_items.each { |offer_item| new_offer.offer_items << offer_item.dup } end end end

Nota: este método no requiere ninguna gema externa, pero requiere una versión más reciente de ActiveRecord con el método #dup implementado

Quiero hacer una copia de un registro de registro de activación, 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 hacer esto ...

como:

@newrecord=Record.copy(:id) *perhaps?*


Como podría haber más lógica, al duplicar un modelo, sugeriría crear una nueva clase, en la que manejará toda la lógica necesaria. Para facilitar eso, hay una gema que puede ayudar: clowne

Según sus ejemplos de documentación, para un modelo de usuario:

class User < ActiveRecord::Base # create_table :users do |t| # t.string :login # t.string :email # t.timestamps null: false # end has_one :profile has_many :posts end

Usted crea su clase cloner:

class UserCloner < Clowne::Cloner adapter :active_record include_association :profile, clone_with: SpecialProfileCloner include_association :posts nullify :login # params here is an arbitrary Hash passed into cloner finalize do |_source, record, params| record.email = params[:email] end end class SpecialProfileCloner < Clowne::Cloner adapter :active_record nullify :name end

y luego usarlo:

user = User.last #=> <#User(login: ''clown'', email: ''[email protected]'')> cloned = UserCloner.call(user, email: ''[email protected]'') cloned.persisted? # => false cloned.save! cloned.login # => nil cloned.email # => "[email protected]" # associations: cloned.posts.count == user.posts.count # => true cloned.profile.name # => nil

Ejemplo copiado del proyecto, pero le dará una visión clara de lo que puede lograr.

Para un registro rápido y sencillo me gustaría ir con:

Model.new(Model.last.attributes.reject {|k,_v| k.to_s == ''id''}


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 más 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, por lo que:

old_task = Task.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_date , y todos los demás atributos lo mismo que la tarea original. Usando 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.


La forma fácil es:

#your rails >= 3.1 (i was done it with Rails 5.0.0.1) o = Model.find(id) # (Range).each do |item| (1..109).each do |item| new_record = o.dup new_record.save end

O

# if your rails < 3.1 o = Model.find(id) (1..109).each do |item| new_record = o.clone new_record.save end


Para obtener una copia, use el método de clonación (o duplicación de rieles 3.1):

# rails < 3.1 new_record = old_record.clone #rails >= 3.1 new_record = old_record.dup

Entonces puedes cambiar los campos que quieras.

ActiveRecord anula el clon de Object # incorporado para darle un nuevo registro (no guardado en la base de datos) con una ID sin asignar.
Tenga en cuenta que no copia asociaciones, por lo que tendrá que hacerlo manualmente si lo necesita.

Rails 3.1 clone es una copia superficial, use dup en su lugar ...


Si necesitas una copia profunda con asociaciones, te recomiendo la gema deep_cloneable .


También puedes consultar la acts_as_inheritable gema.

"Actúa como hereditaria es una gema de Ruby escrita específicamente para los modelos Rails / ActiveRecord. Está diseñada para 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 desde el modelo padre ".

Al agregar acts_as_inheritable a sus modelos, tendrá acceso a estos métodos:

atributos heredados

class Person < ActiveRecord::Base acts_as_inheritable attributes: %w(favorite_color last_name soccer_team) # Associations belongs_to :parent, class_name: ''Person'' has_many :children, class_name: ''Person'', foreign_key: :parent_id end parent = Person.create(last_name: ''Arango'', soccer_team: ''Verdolaga'', favorite_color:''Green'') son = Person.create(parent: parent) son.inherit_attributes son.last_name # => Arango son.soccer_team # => Verdolaga son.favorite_color # => Green

relaciones hereditarias

class Person < ActiveRecord::Base acts_as_inheritable associations: %w(pet) # Associations has_one :pet end parent = Person.create(last_name: ''Arango'') parent_pet = Pet.create(person: parent, name: ''Mango'', breed:''Golden Retriver'') parent_pet.inspect #=> #<Pet id: 1, person_id: 1, name: "Mango", breed: "Golden Retriver"> son = Person.create(parent: parent) son.inherit_relations son.pet.inspect # => #<Pet id: 2, person_id: 2, name: "Mango", breed: "Golden Retriver">

Espero que esto le pueda ayudar.


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

En su caso, probablemente desee hacer uso de las opciones de regex , regex o prefix disponibles en la configuración DSL.

Admite la duplicación recursiva fácil y automática de las has_many has_one , has_many y has_and_belongs_to_many , preprocesamiento de campos y una DSL de configuración altamente flexible y potente que se puede aplicar tanto al modelo como sobre la marcha.

Asegúrese de revisar la documentación de la ameba, pero su uso es bastante fácil ...

sólo

gem install amoeba

o agregar

gem ''amoeba''

a tu Gemfile

A continuación, agregue el bloque de ameba a su modelo y ejecute el método dup 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 varias 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 los campos para ayudar a indicar la singularidad 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:

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, solo habilite ameba en modelos infantiles también

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 revisar la documentación.

¡Disfrutar! :)



Usualmente solo copio los atributos, cambiando lo que necesito cambiar:

new_user = User.new(old_user.attributes.merge(:login => "newlogin"))