如何在Rails模型中克隆单个属性?这不起作用:
irb(main):309:0> u.reload
=> #<User id: 1, username: "starrychloe", ...
irb(main):310:0> u2 = u.dup
=> #<User id: nil, username: "starrychloe", ...
irb(main):311:0> u2 = u.clone
=> #<User id: 1, username: "starrychloe", ...
irb(main):312:0> u2.username = u.username.clone
=> "starrychloe"
irb(main):313:0> u2.username = 'star'
=> "star"
irb(main):314:0> u.username ############ Changes original
=> "star"
这两个都没有:
irb(main):320:0> u.reload
=> #<User id: 1, username: "starrychloe", ...
irb(main):321:0> u2 = u.clone
=> #<User id: 1, username: "starrychloe", ...
irb(main):322:0> u2[:username] = u[:username].clone
=> "starrychloe"
irb(main):323:0> u2.username = 'cow'
=> "cow"
irb(main):324:0> u.username ############ Changes original
=> "cow"
#dup
不会复制ID,并且属性上的#clone
会保留对同一字符串的引用。 This无法解决我的问题。
答案 0 :(得分:2)
u2 = User.new(u.attributes.merge(username: "cow"))
另外,看看这个问题。它有很多关于类似主题的有趣信息: What is the easiest way to duplicate an activerecord record?
答案 1 :(得分:1)
您要复制实例或属性吗?
要复制实例,请使用u2 = u.dup
而不是u2 = u.clone
。
答案 2 :(得分:1)
你可能想看看阿米巴宝石。 https://github.com/rocksolidwebdesign/amoeba
答案 3 :(得分:0)
要使用其属性和取消引用制作实例的副本,您可以执行以下操作:
u2 = u.class.new(u.attributes)
答案 4 :(得分:0)
我最终制作了我想跟踪的每个字段的副本:
@oldUsername = @user.username.clone
User.new
看起来很有前途,但它将副本视为新对象,当它是现有模型时,输出无效表单来编辑视图中的模型:
> app.controller.view_context.form_for u2 do end # This is from Rails console
=> "<form accept-charset=\"UTF-8\" action=\"/users\" class=\"new_user\" id=\"new_user_1\" method=\"post\">
所以它会尝试PATCH到/ users(从视图中),这是无效的,当它应该PATCH到/ users / 1 /.
令人难以置信的是Rails不能正确克隆对象。在Java中,您可以使用u2.setProperty( u.getProperty().clone() )
并确保有一个不会干扰旧对象的新对象。