Last week while working on a project I had to implement a new feature which allowed users to save as when editing an existing project.

At first i decided i was going to create some entirely custom controller actions for that, but I soon had realised the complexity of the task. Alex then came up with the Deep Cloneable gem for me to use, and I have to say this has been a very handy one.

This gem extends the dup method allowing you to select precisely which attributes and relations you want to be cloned.

@project.dup include: {milestones: :tasks }

Here is how we built it:

1. Install the gem Deep Cloneable

2. Create a controller action.

#post method
  def save_as
    @cloned_project = @parent_project = Project.find(params[:id])

    @cloned_project.assign_attributes(params[:project])
    @cloned_project = @parent_project.dup include: { milestones: :tasks }

    if @cloned_project.name == @parent_project.name
      @cloned_project.name = "#{@parent_project.name} (copy)"
    end

    if @cloned_project.save!
      redirect_to projects_path
    else
      render :edit
    end
   end

3. Let’s Clone!

Marin