Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Duplicating a record in Rails 3

I have a prescription model in my Rails 3 application. I am trying to work out the best method of allowing records to be duplicated, but allowing the user to "review" the duplicate before it's saved.

I have read a number of questions/answers on SO (such as this one) which explain how to duplicate/clone the record and then save it - but none which explain how to show the form before save.

Reading the Rails API is appears the clone method is available.

Reading other questions and answers shows that is can be done but there is no example code apart from:

new_record = old_record.dup

The controller code I am currently working with is as follows (the model doesn't have any relationships):

  # POST /prescriptions
  # POST /prescriptions.json
  def create
    @prescription = Prescription.new(params[:prescription])
    @prescription.localip = request.env['REMOTE_ADDR']
    @prescription.employee = @prescription.employee.upcase

    respond_to do |format|
      if @prescription.save
        format.html { redirect_to @prescription, notice: 'Prescription was successfully created.' }
        format.json { render json: @prescription, status: :created, location: @prescription }
      else
        format.html { render action: "new" }
        format.json { render json: @prescription.errors, status: :unprocessable_entity }
      end
    end
  end

I am going to be linking to this clone action from the view with:

<%= link_to "Create another like this?", clone_prescription_url(@prescription), :method => :put %>

Is it as simple as adding an action to my controller like this?

def clone
 @prescription = Prescription.find(params[:id])
 @prescription.dup
 @prescription.save
end

Apologies if the above code is completely wrong, I'm trying to get my head around it! I've seen someone do exactly what I'm trying to achieve with the cloning - but not with the editing before save.

The user that's duplicating won't have permission to edit a record once saved. It's purely for the intial data entry.

like image 674
dannymcc Avatar asked Aug 16 '12 18:08

dannymcc


People also ask

How do you duplicate a record in rails?

You generally use #clone if you want to copy an object including its internal state. This is what Rails is using with its #dup method on ActiveRecord. It uses #dup to allow you to duplicate a record without its "internal" state (id and timestamps), and leaves #clone up to Ruby to implement.

What is DUP in Ruby?

The dup() is an inbuilt method in Ruby returns the number itself. Syntax: num1.dup() Parameters: The function needs a number. Return Value: It returns itself only.


2 Answers

To do this, you're going to have to create a new instance of your Prescription class. "dup" works, but you're assuming it overwrites the existing record. Only methods that end with a bang(!) tend to do that.

Your code should be:

def clone
 @prescription = Prescription.find(params[:id])
 @new_prescription = @prescription.dup
 @new_prescription.save
end

or

def clone
 @prescription = Prescription.find(params[:id]).dup
 @prescription.save
end

This isn't testing for times when the :id isn't found.

like image 64
seanyboy Avatar answered Nov 20 '22 19:11

seanyboy


If you want the clone action to allow the user to review the duplicate before it is saved (AKA created), then it is almost like the "new" action, except with filled in fields already.

So your clone method could be a modification of your new method:

def new
  @prescription = Prescription.new()
end
def clone
  @prescription = Prescription.find(params[:id]) # find original object
  @prescription = Prescription.new(@prescription.attributes) # initialize duplicate (not saved)
  render :new # render same view as "new", but with @prescription attributes already filled in
end

In the view, they can then create the object.

like image 23
ronalchn Avatar answered Nov 20 '22 19:11

ronalchn