2012-08-16 22 views
9

Tengo un modelo de prescripción en mi aplicación Rails 3. Estoy tratando de encontrar el mejor método para permitir que los registros se dupliquen, pero permitiendo que el usuario "revise" el duplicado antes de que se guarde.Duplicar un registro en Rails 3

He leído un número de preguntas/respuestas sobre SO (como this) que explican cómo duplicar/clonar el registro y luego guardarlo, pero ninguna que explique cómo mostrar el formulario antes de guardarlo.

Reading the Rails API aparece el método clone está disponible.

lectura other questions y respuestas muestra que se puede hacer, pero no hay código de ejemplo, aparte de:

new_record = old_record.dup 

El código del controlador actualmente estoy trabajando con es el siguiente (el modelo no tiene ningún relaciones):

# 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 

voy a ser ligarse a esta acción clon desde el punto de vista con:

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

¿Es tan simple como agregar una acción a mi controlador de esta manera?

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

Disculpas si el código anterior es completamente incorrecto, ¡estoy tratando de entenderlo! He visto someone hacer exactamente lo que intento lograr con la clonación, pero no con la edición antes de guardar.

El usuario que está duplicando no tendrá permiso para editar un registro una vez guardado. Es puramente para la entrada de datos inicial.

Respuesta

7

Si desea que la acción de clonación le permita al usuario revisar el duplicado antes de que se guarde (AKA creado), entonces es casi como la acción "nueva", excepto que ya tiene campos rellenos.

Así que su método clone podría ser una modificación de su nuevo método:

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 

En la vista, pueden entonces crear el objeto.

5

Para hacer esto, tendrá que crear una nueva instancia de su clase de prescripción. "dup" funciona, pero supones que sobrescribe el registro existente. Solo los métodos que terminan con un bang (!) Tienden a hacer eso.

El código debería ser:

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

o

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

Ésta no es la prueba para los tiempos cuando la: no se encuentra ID.

+0

Creo que esta es la respuesta correcta, ya que los carriles establece el identificador a cero cuando se utiliza 'dup' en un modelo, el tratamiento de como nuevo Ver http://apidock.com/rails/ActiveRecord/Core/dup –

0

Estaba buscando lógica para clonar un registro existente. Tuve que modificar ligeramente la lógica publicada por ronalchn porque cuando intentó ejecutar la segunda declaración de clon obtuve un error de asignación masiva porque intentó copiar id, created_at, updated_at que no están incluidos en mi lista attr_accessible.Así es como he modificado la lógica para conseguir que funcione en mi aplicación que utiliza mi modelo:

@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 
Cuestiones relacionadas