什么是复制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中可用的nullify
, regex
或prefix
选项。
它支持has_one
, has_many
和has_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">
希望这可以帮助你。