我的代码:
class ActiveRecord::Base
def clone!(options = {})
defaults = {:except => [:updated_at, :cerated_at, :id], :shallow => []}
options = defaults.merge(options)
skip_attributes = options[:except] or false #attributes not to clone at all
shallow_attributes = options[:shallow] or false # non-recursivly cloned attributes
options[:except] << self.class.to_s.foreign_key # add current class to exceptions to prevent infinite loop
new_model = self.class.new
self.attributes.each_pair do |attribute, value|
skip_attribute = (skip_attributes ? skip_attributes.map{|a| a.to_s}.include?(attribute) : false)
next if skip_attribute
shallow_copy = (shallow_attributes ? shallow_attributes.map{|s| s.to_s}.include?(attribute) : false)
if attribute =~ /_id\z/ and (not shallow_copy)
# assume reference to a different object
model_table_name = attribute.gsub(/_id\z/, "")
model_name = model_table_name.camelize
referenced_object = model_name.constantize.find(value).clone!(options)
puts attribute.inspect
puts referenced_object.inspect
new_model.send("#{attribute}=", referenced_object[:id])
else
new_model.send("#{attribute}=", value)
end
end
new_model.save!
end
end
因此,调用该方法的一种方法是:
b = MyObject.find(432).clone!({:shallow =&gt; [:account_id,:user_id,:ext_integration_id,:category_id],:except =&gt; [:closed_comment_id]})
问题是MyObject HAS MANY OtherObjects,因此MyObject本身并不直接引用OtherObjects,因为OtherObjects具有MyObject的外键。
如何找出具有这种关系的模型的名称?
答案 0 :(得分:2)
我不确定这是否完全适用,因为我不确定我究竟想要复制什么以及你不想复制什么,但是...
对于ActiveRecord 3.2,您可以从Amoeba gem中获得一些好用。
它支持has_one
,has_many
和has_and_belongs_to_many
关联的简单和自动递归复制,字段预处理以及高度灵活且功能强大的配置DSL,可以应用于模型和苍蝇。
请务必查看Amoeba Documentation,但使用非常简单......
刚
gem install amoeba
或添加
gem 'amoeba'
到您的Gemfile
然后将变形虫块添加到模型中并照常运行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
您的新帖子应该包含最初与之关联的所有标记,并且所有评论也应该重复。您可以通过DSL禁用各种记录的复制,您可以在文档中阅读这些记录,但是,例如,如果您想保留标记,而不是注释,则可以执行以下操作:
class Post < ActiveRecord::Base
has_many :comments
has_and_belongs_to_many :tags
amoeba do
include_field :comments
end
end
这应该会导致新帖子与旧帖子重新关联,但不会重复评论。
如果您启用了Amoeba,Amoeba也会自动递归到子记录中
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
希望有所帮助:)
答案 1 :(得分:0)