2014-01-27 511 views
2

如何在Rails模型中克隆单个属性?这不起作用:如何克隆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不会解决我的问题。

+1

使用'dup'工程,不应该改变你原来的实例属性。我已经在Rails 4和Ruby 2上测试过了。'dup'不会复制id,因为它初始化实例的一个新副本,因此不会是db中的同一个对象。 –

回答

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

因此,这将尝试补丁/用户(从视图),这是无效的,当它应该补丁/用户/ 1 /。

令人难以置信的是,Rails不会正确克隆对象。在Java中,您可以使用u2.setProperty(u.getProperty().clone()),并确保有一个不会干扰旧的对象。

1

是否要复制实例或属性?

要复制实例,请使用u2 = u.dup而不是u2 = u.clone

+0

对不起 - 我可能误解了。你也试图保留身份证吗? – Swards

+0

是的,我必须保留这个ID,这样一旦保存,它就不会在数据库中插入一条新记录。 – Chloe

0

为了与它的属性实例的副本,并取消引用你可以这样做:

u2 = u.class.new(u.attributes) 
+0

奇特的,但它认为这是一个新的对象。有没有办法解决这个问题? 'app.controller.view_context.form_for u2 do end':'

... '。 – Chloe

+0

你在视图中做这件事的任何原因? – bjhaid

+0

?我不是这样认为的。这是来自Rails控制台。 – Chloe