Search code examples
ruby-on-railsruby-on-rails-4rails-activerecordrails-modelsamoeba-gem

Rails 4 Duplicating Model Objects and Merging New Object attribtues (Amoeba Gem)


What I'm doing: Duplicating a record of my Project model then overwriting the modified attributes from an object submitted by a form. The new record should be modified but have all the associations as the original.

The first step I took was to duplicate a AR Model object, including its associations, which I'm doing with Amoeba gem.

projects_controller.rb

...
def create
    if params[:copy]
        orig_project = Project.find params[:copy]
        @new_project = orig_project.amoeba_dup
...

Now I would like to merge my project_params into the @new_project object overwriting the attributes if the attributes are different.

projects_controller.rb

...
def create
    if params[:copy]
        orig_project = Project.find params[:copy]
        @new_project = orig_project.amoeba_dup

        my_merge_method(@new_project,project_params)
...
        if @new_project.save

Could anyone provide a good way to do this with some rails magic? Thanks


Solution

  • Messing around in the rails console I have found that the method update_attributes for AR model objects does what I want.

    For Example

    new_project = orig_project.amoeba_dup
    new_project.update_attributes(project_params)
    

    ...will leave the associations intact but overwrite the new_project with the project_params

    Here is the rails console output to prove it.

    35: def create
        36:   if params[:copy]
        37:     orig_project = Project.find params[:copy]
        38:     @project = orig_project.amoeba_dup
        39: 
     => 40:     binding.pry
        41:   else
        42:     @project = Project.new(project_params)
        43:   end
        44:   
        45:   respond_to do |format|
        46:     if @project.save
        47:       format.html { redirect_to @project, notice: 'Project was successfully created.' }
        48:       format.json { render action: 'show', status: :created, location: @project }
        49:     else
        50:       format.html { render action: 'new' }
        51:       format.json { render json: @project.errors, status: :unprocessable_entity }
        52:     end
        53:   end
        54: end
    
    [1] pry(#<ProjectsController>)> params[:copy]
    => "201"
    [2] pry(#<ProjectsController>)> @project
    => #<Project:0x00000005c38e58
     id: nil,
     name: "Corn Flour Milling with Setup",
     scheduled_start_date: Tue, 29 Dec 2015,
     estimated_end_date: Wed, 27 Jan 2016,
     employees_needed: 2,
     incoming_packaging: "Boxes",
     final_product_packaging: "Boxes",
     sample_instructions: "One 18 oz every pallet.\r\nMilled Corn Flour\r\nLot Number\r\nBag Number\r\nNet Weight",
     project_description: "Mill the piss out of this.",
     project_type: "Production",
     building_id: "5",
     paid_status: false,
     material_total_weight_lbs: 40000,
     shifts: 1.0,
     shift_hrs: 8,
     rate_lb_hr: 2000,
     company_id: 1,
     created_at: nil,
     updated_at: nil>
    [4] pry(#<ProjectsController>)> @project.setups
    => [#<Setup:0x00000005c73210 id: 22, created_at: Thu, 21 Jan 2016 14:33:09 UTC +00:00, updated_at: Thu, 21 Jan 2016 14:33:09 UTC +00:00>]
    [5] pry(#<ProjectsController>)> project_params
    => {"name"=>"Corn Flour Milling with Setup",
     "scheduled_start_date"=>"2016-03-25", #changed this value
     "estimated_end_date"=>"2016-03-30", #changed this value
     "employees_needed"=>"2",
     "incoming_packaging"=>"Boxes",
     "final_product_packaging"=>"Boxes",
     "sample_instructions"=>"One 18 oz every pallet.\r\nMilled Corn Flour\r\nLot Number\r\nBag Number\r\nNet Weight",
     "project_description"=>"Mill the piss out of this.",
     "project_type"=>"Production",
     "building_id"=>"5",
     "paid_status"=>"false",
     "material_total_weight_lbs"=>"40000",
     "shifts"=>"1.0",
     "shift_hrs"=>"8",
     "rate_lb_hr"=>"2000",
     "company_id"=>"1"}
    [7] pry(#<ProjectsController>)> @project.update_attributes(project_params)
       (0.6ms)  BEGIN
      Company Load (1.3ms)  SELECT  "companies".* FROM "companies" WHERE "companies"."id" = $1 LIMIT 1  [["id", 1]]
      SQL (1.3ms)  INSERT INTO "projects" ("name", "scheduled_start_date", "estimated_end_date", "employees_needed", "incoming_packaging", "final_product_packaging", "sample_instructions", "project_description", "project_type", "building_id", "paid_status", "material_total_weight_lbs", "shifts", "shift_hrs", "rate_lb_hr", "company_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18) RETURNING "id"  [["name", "Corn Flour Milling with Setup"], ["scheduled_start_date", "2016-03-25"], ["estimated_end_date", "2016-03-30"], ["employees_needed", 2], ["incoming_packaging", "Boxes"], ["final_product_packaging", "Boxes"], ["sample_instructions", "One 18 oz every pallet.\r\nMilled Corn Flour\r\nLot Number\r\nBag Number\r\nNet Weight"], ["project_description", "Mill the piss out of this."], ["project_type", "Production"], ["building_id", "5"], ["paid_status", "f"], ["material_total_weight_lbs", 40000], ["shifts", 1.0], ["shift_hrs", 8], ["rate_lb_hr", 2000], ["company_id", 1], ["created_at", "2016-01-21 20:07:26.508713"], ["updated_at", "2016-01-21 20:07:26.508713"]]
      SQL (1.8ms)  INSERT INTO "projects_setups" ("setup_id", "project_id") VALUES ($1, $2)  [["setup_id", 22], ["project_id", 217]]
       (32.1ms)  COMMIT
    => true
    [8] pry(#<ProjectsController>)>