2011-01-16 7 views
8

Tengo 2 acciones: Editar y actualizar. El formulario en Editar envía los valores a Acción de actualización. Cuando se produce un error al guardar un modelo, edito la teplate de edición, donde el usuario ve errores y los campos se llenan previamente con lo que rellenó. Hay un gran pero para mí: en el panel de URL del navegador del usuario hay/usuario/actualización, incluso cuando (y porque) I prestados plantilla de edición. ¿Puedo de alguna manera cambiar eso con pasar algunos parámetros para representar el método en la acción de actualización? No quiero que el usuario vea que hay alguna acción (de actualización) aparte de editar. ¿Es posible?¿Renderizar plantilla y cambiar cadena url en el navegador?

Respuesta

1

Hay dos maneras de evitar esto:

1) redirección desde la acción de actualización de nuevo a la acción de edición, en lugar de hacer que la plantilla, y pasar los mensajes de error y los atributos que desea utilizar para rellenar el objeto que se está editando. Esto dará como resultado que la URL sea/user/edit.

 
def update 
    @user = User.find(params[:id]) 
    if @user.update_attributes params[:user] 
    ... 
    else 
    redirect_to edit_user_path(@user, :messages => @user.errors) 
    end 
end 

2) correo postal a la acción de edición en lugar de la acción de actualización y retire la acción de actualización en su totalidad. Puedes usar request.post? en su acción de edición para verificar si la solicitud es una solicitud de publicación u obtención y luego realizar su actualización y editar acciones usando la misma definición de función.

 
def edit 
    @user = User.find(params[:id]) 
    if request.post? 
    @user.update_attributes params[:user] 
    ... 
    else 
    ... 
    end 
end 

NOTA: Tenga en cuenta sin embargo que no se puede siempre realmente ocultar la acción POST desde el cliente, ya que siempre se puede ver el código fuente y ver la acción a la que está publicando en su forma.

+1

Al hacer la opción 1, termino con una URL como 'artículos/1/edit? Messages =% 23 'y los errores no se muestran. – Cameron

6

Aquí es la tercera forma de evitar esto:

En su routes.rb

resources :users 
match 'users/:id/edit' => 'users#update', :via => :put, :as => :put_user 

En su opinión (edit.html.erb por ejemplo)

<%= form_for @user, :url => put_user_path do |f| %> 
    ... 
<% end %> 

En su controlador (users_controller.rb por ejemplo)

def update 
    @user = User.find(params[:id]) 
    if @user.update_attributes(params[:user]) 
    ... 
    else 
    render 'edit' 
    end 
end 
+0

Esto funcionó bien. Gracias. –

0

Una versión ligeramente más moderno basado en la respuesta de CL Chang

resources :jobs, except: [:update] do 
    member do 
     patch 'edit', action: :update, :as => :update_edit 
    end 
end 

Esto genera todas las rutas de descanso estándar, a excepción de la ruta de actualización estándar. (Si no desea que todas las acciones, entonces se puede utilizar only: [<your routes not including :update>]

Además, genera

update_edit_job PATCH /jobs/:id/edit(.:format) 

Ahora que acaba de actualizar su formulario para especificar la ruta

<%= form_for @job, :url => update_edit_job_path do |f| %> 
    ... 
<% end %> 

por lo , en lugar de enviar a/actualizar a través de parche, va a/trabajos // editar a través de parche, y esto golpea su acción de actualización

ahora si hay un error, puede procesar la edición, y todo th e errores serán visibles - pero el usuario no se dará cuenta de que la URL es diferente a la edición de un (porque sólo el método es diferente)

def update 
    @job = Job.find(params[:id]) 
    if @job.update_attributes(user_params) 
    #redirect somewhere??? 
    else 
    render 'edit' 
    end 
end 
Cuestiones relacionadas