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.
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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With