什么是复制activerecordlogging最简单的方法?

我想制作一个activerecordlogging的副本,更改进程中的单个字段(除了id )。 什么是最简单的方法来完成这个?

我意识到我可以创build一个新的logging,然后迭代每个字段的字段逐个字段 – 但我想一定有一个更简单的方法来做到这一点…

如:

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

要获得副本,请使用克隆(或用于rails 3.1的方法):

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

那么你可以改变你想要的领域。

ActiveRecord覆盖内置的Object#克隆 ,为您提供一个未分配ID的新(未保存到数据库)logging。
请注意,它不会复制关联,因此如果需要,您必须手动执行此操作。

Rails 3.1的克隆是一个浅拷贝,用dup来代替…

根据您的需求和编程风格,您也可以使用类和合并的新方法的组合。 缺less一个更好的简单例子,假设你有一个任务计划在某个date,你想复制到另一个date。 任务的实际属性并不重要,所以:

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

将创build一个新的任务:id => nil:scheduled_on => some_new_date ,以及所有其他属性与原始任务相同。 使用Task.new,你将不得不明确地调用保存,所以如果你想自动保存,将Task.new更改为Task.create。

和平。

你可能也喜欢ActiveRecord 3.2的Amoeba gem 。

在你的情况下,你可能想要使用configurationDSL中可用的nullifyregexprefix选项。

它支持has_onehas_manyhas_and_belongs_to_many关联的轻松自动recursion重复,字段预处理以及高度灵活和强大的configurationDSL,可以应用于模型和飞行。

请务必查看Amoeba文档,但使用非常简单…

只是

 gem install amoeba 

或添加

 gem 'amoeba' 

到你的Gemfile

然后将amoeba块添加到您的模型并照常运行dup方法

 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 

您还可以控制以多种方式复制哪些字段,但是例如,如果您想防止意见被复制,但是您希望维护相同的标记,则可以执行如下操作:

 class Post < ActiveRecord::Base has_many :comments has_and_belongs_to_many :tags amoeba do exclude_field :comments end end 

您还可以预处理字段,以帮助用前缀和后缀以及正则表示唯一性。 另外,还有很多选项,所以你可以用最可读的风格来编写你的目的:

 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 

关联的recursion复制很容易,只需在子模型上启用阿米巴

 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 

configurationDSL还有更多选项,所以一定要查看文档。

请享用! 🙂

如果你不想复制id,使用ActiveRecord :: Base#dup

我通常只是复制属性,改变我需要改变的任何东西:

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

如果你需要深度复制关联,我推荐deep_cloneable gem。

简单的方法是:

 #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 

要么

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

你也可以检查acts_as_inheritable gem。

“Acts As Inherited是一个专门为Rails / ActiveRecord模型编写的Ruby Gem,它可以用于自我指涉关联 ,也可以用于拥有共享可inheritance属性的父代的模型,这样可以让你inheritance任何属性或从父模型的关系“。

通过将acts_as_inheritable添加到模型中,您将可以访问这些方法:

inherit_attributes

 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 

inherit_relations

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

希望这可以帮助你。