Question

How to Duplicate an ActiveRecord Record in Ruby on Rails

rubyruby-on-railsrails-activerecord

Question

I want to duplicate an ActiveRecord object in Ruby on Rails while changing one field during the copy process. The new record should have a different id, and I may want to update another attribute before saving it.

I know I could create a new record manually and copy each field one by one, but I assume there is a simpler Rails way to do this.

For example, I am looking for something conceptually like:

new_record = Record.copy(:id)

What is the easiest and most idiomatic way to duplicate an ActiveRecord record?

Short Answer

By the end of this page, you will understand how Rails duplicates ActiveRecord objects, when to use dup, what gets copied and what does not, and how to safely modify attributes before saving the new record.

Concept

In Ruby on Rails, the usual way to duplicate an ActiveRecord model instance is to use dup.

new_record = old_record.dup

This creates a new model object with the same attribute values as the original, but it is treated as a new record. That means Rails does not keep the original primary key value, so when you save the duplicate, it gets a new id.

Example:

new_post = post.dup
new_post.title = "Copied: #{post.title}"
new_post.save!

Why this matters:

  • It avoids manually assigning every column.
  • It is the idiomatic Rails approach for copying a record.
  • It makes cloning data safer and faster in real projects.

Important detail: dup copies the model's attributes, but it does not automatically duplicate associated records such as has_many children. If you need a deep copy, you usually handle associations separately.

In practice, dup is most useful when:

  • creating a template-based record
  • copying drafts
  • reusing existing configuration
  • cloning a row with only a few changed fields

Mental Model

Think of an ActiveRecord object like a filled-out form.

  • The original record is the submitted form already stored in the database.
  • dup gives you a fresh blank submission that is pre-filled with the same answers.
  • The record looks similar, but it is not the same database row.
  • When you save it, Rails stores it as a new row with a new id.

So dup is like saying: give me the same data, but as a new record I can edit and save separately.

Take Quiz

Syntax and Examples

The basic syntax is:

copy = original.dup

Then you can change any attributes before saving:

copy = original.dup
copy.name = "New Name"
copy.save!

Example

Suppose you have a Product model:

product = Product.find(1)

Duplicate it:

new_product = product.dup
new_product.name = "#{product.name} (Copy)"
new_product.save!

What happens here

  • product.dup copies the attribute values
  • new_product is marked as a new unsaved record
  • id is not copied as a usable database identity
  • changing name only affects the new object
  • save! inserts a new row into the database

Common pattern

copied_user = user.dup
copied_user.email = "new-email@example.com"
copied_user.save!

This is especially useful when one field must be unique, such as email, slug, or code.

Step by Step Execution

Consider this code:

article = Article.find(1)
copy = article.dup
copy.title = "#{article.title} (Copy)"
copy.save!

Step by step:

  1. Article.find(1) loads the existing record from the database.
  2. article.dup creates a new Article object with copied attributes.
  3. The new object is not saved yet.
  4. Its id is not treated as the original record's primary key.
  5. copy.title = ... changes one field on the duplicate.
  6. copy.save! inserts a brand new row into the database.

If the original row looked like this:

idtitlestatus
1Intro to APIdraft

After duplication and saving:

idtitlestatus
1Intro to APIdraft
2Intro to API (Copy)draft

The original record remains unchanged.

Real World Use Cases

Here are common places where record duplication is useful:

  • Copying templates: create a new invoice from a saved invoice template.
  • Duplicating drafts: make a new blog post based on an old one.
  • Reusing configuration: copy app settings, pricing plans, or workflow rules.
  • Cloning catalog items: duplicate a product and change only the SKU or name.
  • Admin tools: let staff quickly create similar records without re-entering all fields.

Example in an admin panel:

new_plan = existing_plan.dup
new_plan.name = "Pro Plan 2026"
new_plan.save!

This saves time and reduces manual input mistakes.

Take Quiz

Real Codebase Usage

In real Rails codebases, developers often use dup together with validation, guard clauses, and attribute cleanup.

Pattern: duplicate and adjust unique fields

copy = post.dup
copy.slug = nil
copy.title = "#{post.title} Copy"
copy.save!

This is common when fields like slug must be regenerated.

Pattern: guard clause before copying

return unless post.published?

copy = post.dup
copy.status = "draft"
copy.save!

This prevents invalid duplication based on business rules.

Pattern: service object

In larger applications, duplication logic is often moved into a service:

class DuplicateProduct
  def self.call(product)
    copy = product.dup
    copy.name = "#{product.name} Copy"
    copy.sku = nil
    copy.save!
    copy
  end
end

This keeps controllers and models cleaner.

Pattern: duplicate associations manually

If a record has child rows, developers usually duplicate them explicitly:

new_order = order.dup
new_order.save!

order.line_items.each do |item|
  new_item = item.dup
  new_item.order = new_order
  new_item.save!
end

That is because dup only handles the model itself, not a full deep copy of related data.

Common Mistakes

1. Forgetting to save the duplicate

Broken example:

copy = product.dup
copy.name = "Copy"

This creates the object in memory, but nothing is written to the database until you call save or save!.

Fix:

copy = product.dup
copy.name = "Copy"
copy.save!

2. Expecting associations to be copied automatically

Broken assumption:

new_order = order.dup
new_order.save!

This does not copy line_items, comments, or other related records.

Fix: duplicate associations manually when needed.

3. Forgetting unique validations

Broken example:

copy = user.dup
copy.save!

If email must be unique, this may fail validation.

Fix:

copy = user.dup
copy.email = "new@example.com"
copy.save!

4. Modifying the original instead of the copy

Broken example:

copy = product
copy.name = "Changed"

This does not duplicate anything. Both variables point to the same object.

Fix:

copy = product.dup
copy.name = "Changed"

5. Assuming every field should be copied

Some fields should usually be reset, such as:

  • unique identifiers
  • timestamps in some workflows
  • status fields
  • generated tokens

Example:

copy = report.dup
copy.token = nil
copy.status = "draft"
copy.save!

Comparisons

ApproachWhat it doesWhen to use itNotes
record.dupCopies attributes into a new unsaved recordStandard record duplicationMost idiomatic Rails approach
Manual assignmentBuilds a new object field by fieldWhen only a few fields are neededMore verbose but very explicit
cloneCopies the object more literally in RubyRarely used for ActiveRecord duplicationUsually not the preferred Rails choice
new(attributes)Creates a new record from selected attributesWhen you want full controlUseful if you want to exclude many fields

dup vs manual copying

# Using dup
copy = product.dup
copy.name = "Copy"

# Manual copying
copy = Product.new(
  name: product.name,
  price: product.price,
  description: product.description
)

dup is shorter and easier when most attributes should stay the same.

dup vs clone

In Rails, dup is typically the right choice for making a new database record. clone is a lower-level Ruby object copy and is not usually the tool developers reach for when duplicating ActiveRecord rows.

Take Quiz

Cheat Sheet

Quick reference

copy = record.dup
copy.some_field = "New value"
copy.save!

Key points

  • dup creates a new unsaved ActiveRecord object
  • the duplicate gets a new id when saved
  • change attributes before saving
  • associations are not deep-copied automatically
  • unique fields may need to be changed manually

Typical pattern

copy = original.dup
copy.name = "#{original.name} Copy"
copy.slug = nil
copy.save!

Use save vs save!

  • save returns true or false
  • save! raises an exception if validation fails

Watch out for

  • uniqueness validations
  • child associations not being copied
  • accidentally editing the original object instead of the duplicate

FAQ

What is the easiest way to duplicate an ActiveRecord record?

Use dup:

copy = record.dup

Then update fields and save it.

Does dup copy the id?

No. The duplicate is treated as a new record and gets a new id when saved.

Does dup copy associated records too?

No. It copies the model's own attributes, not related has_many or similar associations.

Why does saving a duplicated record sometimes fail?

Usually because of validations, especially uniqueness validations on fields like email, slug, or sku.

Should I use dup or clone in Rails?

For duplicating ActiveRecord records, dup is the normal and recommended approach.

Can I change attributes before saving the copy?

Yes. That is one of the main reasons to use dup.

copy = post.dup
copy.title = "New title"
copy.save!
Take Quiz

Mini Project

Description

Build a small Rails-style example that duplicates a blog post, changes its title, resets a unique slug, and saves the new record. This demonstrates the most common real-world pattern for copying existing data into a new database row.

Goal

Create a safe duplicate of an existing ActiveRecord record while updating selected fields before saving.

Requirements

  • Find an existing record by ID
  • Duplicate it using the Rails idiomatic approach
  • Change at least one normal field such as title
  • Reset one field that may need to be unique, such as slug
  • Save the copied record as a new database row
Take Quiz

Keep learning

Related questions

View more