2009-11-20 10 views
7

Con frecuencia me he encontrado con la situación en la que quiero actualizar muchos registros a la vez, como hace GMail al configurar muchos mensajes como "leer" o "no leído".Rieles Acciones silenciosas Índice Poner

rieles alienta esto con el método de la 'actualización' de una clase ActiveRecord - Comment.update (teclas, valores)

Ejemplo - http://snippets.dzone.com/posts/show/7495

Ésta es una gran funcionalidad, pero difícil de mapa a una ruta de descanso . En cierto sentido, me gustaría ver una: poner acción en una colección. En rutas, podríamos añadir algo así como

map.resources :comments, :collection => { :update_many => :put } 

Y luego, en la forma, que haría esto ...

<% form_for @comments do |f| %> 
    ... 

Esto no funciona en muchos niveles. Si haces esto:: collection => {: update_many =>: put}, rails enviará una publicación a la acción de índice (CommentsController # index), quiero que vaya a la acción 'update_many'. En cambio, puede hacer a: collection => {: update_many =>: post}. Esto al menos irá a la acción correcta en el controlador.

Y, en lugar de < forma% para @comments ... que tiene que hacer lo siguiente:

<% form_for :comments, :url => { :controller => :comments, :action => :update_many } do |f| %> 

Se trabajará Aceptar esta manera

aún no es perfecto - se siente un poco como nos No lo estoy haciendo de la manera 'Rails'. También parece que: post y delete también tienen sentido en un controlador de colección.

Estoy publicando aquí para ver si hay algo que me perdí al configurar esto. ¿Alguna otra idea sobre cómo hacer un nivel de colección de forma relajada: publicar,: poner,: eliminar?

+0

Soy consciente de que mi respuesta se limita a proporcionar otra solución al problema que inspiró a su pregunta. Lo he editado, refleja eso. – EmFi

Respuesta

1

A menudo agrego acciones basadas en colección update_multiple y destroy_multiple a un controlador RESTful.

Consulte este Railscast en la actualización a través de casillas de verificación. Debería darte una buena idea de cómo abordarlo, volver y agregar a esta pregunta si tienes problemas.

+0

Gracias por esto: parece que el uso de 'form_for' no funciona con la acción: poner. Cuando cambié a 'form_tag' (como demuestra Ryan B.), ahora va a la acción correcta y funciona correctamente. No intenté averiguar por qué. Una pequeña cosa: me gusta usar el bloque 'fields_for' para generar los campos de entrada para cada registro (f.text_field). Ryan no usa fields_for en su screencast (tal vez porque es anterior al helper) y usa los métodos _tag. 'fields_for' está bien para usar aquí. – Swards

2

Me he encontrado con algunas situaciones como las que describes. Las primeras veces que las implementé son casi idénticas a la que sugieres.

Alrededor de la tercera vez que llegué a este problema, me di cuenta de que cada elemento que estoy actualizando tiene una relación de belongs_to común con otra cosa. Usualmente un usuario. Esa es exactamente la epifanía que necesitas para darle sentido a esto de manera RESTANTE. También lo ayudará a limpiar y limpiar el formulario/controlador.

No piense que está actualizando un montón de mensajes, piense que se trata de una actualización de un usuario.

Aquí hay un código de ejemplo que he utilizado en el pasado para resaltar la diferencia. Suponiendo que queremos operaciones masivas en los mensajes que pertenecen a la current_user ...

A partir de los carriles 2.3 podemos añadir

accepts_nested_attributes_for :messages 

al modelo de usuario. Asegúrese de que messages_attributes forme parte de attr_accessible o attr_protected.

A continuación, cree la ruta:

map.resources :users, :member => {:bulk_message_update, :method => :put} 

Luego agregar la acción al controlador. Con las capacidades de AJAX);

def bulk_message_update 
    @user = User.find(params[:id]) 
    @user.update_attributes(params[:user]) 
    if @user.save 
    respond_to do |format| 
     format.html {redirect} 
     format.js {render :update do |page| 
      ... 
     } 
    end  
    else 
    .... 
end 

Luego, su forma se verá así:

<% form_for current_user, bulk_message_update_user_url(current_user), 
    :html => {:method => :put} do |f| %> 
    <% f.fields_for :messages do |message| %> 
    form for each message 
    <% end %> 
    <%= sumbit_tag %> 
<% end %> 
+1

si los mensajes son un subrecurso de usuario, entonces parece apropiado hacer el PUT a/user/123/messages. ¿Qué piensas? –

Cuestiones relacionadas