2012-08-16 11 views
9

Ich habe ein Verschreibungsmodell in meiner Rails 3-Anwendung. Ich versuche, die beste Methode zu finden, um das Duplizieren von Datensätzen zu erlauben, aber dem Benutzer zu erlauben, das Duplikat zu "überprüfen", bevor es gespeichert wird.Duplizieren eines Datensatzes in Rails 3

Ich habe eine Reihe von Fragen/Antworten auf SO (wie this eins) gelesen, die erklären, wie Sie den Datensatz duplizieren/klonen und dann speichern - aber keine, die erklären, wie das Formular vor dem Speichern angezeigt wird.

Beim Lesen der Rails-API wird die Methode clone angezeigt.

Lesen other questions und Antworten zeigt, die getan werden kann, aber es gibt kein Beispiel-Code abgesehen von:

new_record = old_record.dup 

Der Controller Code, den ich zur Zeit mit ist arbeite wie folgt (das Modell hat keine Beziehungen):

# 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 dieser Klon Aktion zu verknüpfen aus der Sicht werde mit:

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

Ist es so einfach wie das Hinzufügen einer Aktion zu meinem Controller?

Entschuldigung, wenn der obige Code völlig falsch ist, versuche ich, meinen Kopf herum zu bekommen! Ich habe gesehen, someone tun genau das, was ich versuche mit dem Klonen zu erreichen - aber nicht mit der Bearbeitung vor dem Speichern.

Der Benutzer, der dupliziert wird, ist nicht berechtigt, einen Datensatz nach dem Speichern zu bearbeiten. Es ist rein für die ursprüngliche Dateneingabe.

Antwort

7

Wenn die Klonaktion dem Benutzer ermöglichen soll, das Duplikat zu überprüfen, bevor es gespeichert wird (AKA erstellt), dann ist es fast wie die "neue" Aktion, außer mit bereits ausgefüllten Feldern.

So könnte Ihre Klon-Methode eine Modifikation der neuen Methode:

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 der Ansicht können sie dann das Objekt erstellen.

5

Um dies zu tun, müssen Sie eine neue Instanz Ihrer Prescription-Klasse erstellen. "dup" funktioniert, aber Sie gehen davon aus, dass der vorhandene Datensatz überschrieben wird. Nur Methoden, die mit einem Knall (!) Enden, tendieren dazu.

sollte Ihr Code sein:

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

oder

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

Dies testet nicht für Zeiten, in denen die: ID nicht gefunden wird.

+0

Ich denke, das ist die richtige Antwort, da Rails die ID auf Null setzt, wenn mit 'dup' auf einem Modell, Behandlung es als neu. Siehe http://apidock.com/rails/ActiveRecord/Core/dup –

0

Ich suchte nach Logik, um einen vorhandenen Datensatz zu klonen. Ich musste die von ronalchn gepostete Logik leicht ändern, denn als ich versuchte, die zweite Anweisung von Klon auszuführen, bekam ich einen Massenzuordnungsfehler, weil ich versuchte, ID, created_at, updated_at zu kopieren, die nicht in meiner attr_accessible-Liste enthalten sind.Dies ist, wie ich die Logik geändert, um es in meiner Anwendung mit meinem Modell zu arbeiten:

@old_event = Event.find(params[:id]) # find original object 
@event = Event.new 
@event.field_1 = @old_event.field_1 (statement for each field in attar_accessible) 
render :new # render same view as "new", but with @prescription attributes already filled in