1

我試圖創建一個郵件的多個副本的用戶:如何在Ruby on Rails/ActiveRecord中克隆模型?

users.each do |user| 
    new_message = message.clone 
    new_message.to = user 
    new_message.save! 
end 

然而,這並不一日後用戶的工作。下面是錯誤消息的一部分:

SQL (0.7ms) INSERT INTO "messages" ("content", "to_id") VALUES (?, ?) [["content", "abc"], ["to_id", 1]] 
    (2.5ms) commit transaction 
    User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = 2 LIMIT 1 
    (0.0ms) begin transaction 
    SQL (0.5ms) INSERT INTO "messages" ("content", "id", "to_id") VALUES (?, ?, ?) [["content", "abc"], ["id", 6], ["to_id", 2]] 
SQLite3::ConstraintException: PRIMARY KEY must be unique: INSERT INTO "messages" ("content", "id", "to_id") VALUES (?, ?, ?) 
    (0.0ms) rollback transaction 
Completed 500 Internal Server Error in 130.1ms 

ActiveRecord::StatementInvalid (SQLite3::ConstraintException: PRIMARY KEY must be unique: INSERT INTO "messages" ("content", "id", "to_id") VALUES (?, ?, ?)): 

正如你所看到的,問題是循環運行的第二次,message.clone必須包含以前new_messageid

克隆許多用戶的郵件記錄的正確方法是什麼?當然,我可以手動將每個屬性(我有一個批次多於contentto_id)複製到一個新的新對象Message。但我想知道是否有更好的方法。

回答

4

您可以使用dup,與該idcreated_atupdated_at設置爲nil。這將確保不會拋出主鍵異常,但是如果有其他唯一驗證,它們將失敗。你必須分開處理它們。

users.each do |user| 
    new_message = message.dup 
    new_message.to = user 
    new_message.save! 
end 
+0

正是我在找的東西。爲什麼'clone'會以這種方式行事?奇怪的是,原來的對象最終會從克隆對象的字段中結束。 –

+0

@ muistooshort,是的,謝謝。更新的鏈接。 – vee