acciones custom en Rails 3 (Parte 2 editar multiples registros)

Como lo habia prometido, esta es la ultima parte de mi post sobre multiples acciones en Rails 3. En el post anterior explicaba como poder borrar multiples registros, ahora explicaré como poder editar multiples registros, sin perder la funcionalidad de borrar varios registros, estuve buscando una solución sencilla y muchas usaban trucos con javascript, pero como buen Javero me es dificil estar haciendo trucos o soluciones en el cliente haha, así que implementé algo parecido a un dispatchEvent pero mucho muy básico.

1.- Editar el archivo routes.rb

Bueno aqui tuve que simplificarme las cosas un poco y modifique la ruta existente para borrar registros y crear la nueva ruta.

    
namespace :admin do |admin|
resources :users do
collection do
post 'edit_selected'
post 'evt_dispatch', :as => "evt_dispatch"
put :update_multiple
end
end
end

Como pueden ver es necesario crear una ruta con el método put para realizar la actualización.

2.- Editar el controlador de usuarios para agregar las nuevas acciones
Mi controlador de usuarios quedó de la siguiente manera, (solo muestro las acciones modificadas o necesarias para este post):

  
def edit_selected
@users = User.find(params[:user_ids])
end

def update_multiple
@users = User.find(params[:user_ids])
@users.each do |user|
user.update_attributes!(params[:user].reject { |k,v| v.blank? })
end
flash[:notice] = "Users Updated!"
redirect_to admin_users_path
end

def evt_dispatch
if !(params[:user_ids] == nil)

case params[:button]
when "delete"
del_selected

when "edit"
@users = User.find(params[:user_ids])
render :action => "edit_selected"
end

else
redirect_to admin_users_path, :notice => "Please select at least one user."
end
end

def del_selected

if !(params[:user_ids] == nil)

params[:user_ids].each do |id|
User.delete_all(["id = ?" , id.to_i])
end
flash[:notice] = "Users deleted successfully."
redirect_to admin_users_path

else
redirect_to admin_users_path, :notice => "Please select users to delete."
end
end

Aqui se pueden observar varias cosas, primero que tengo repetida la funcionalidad en la acción edit_selected y en el evento editar de evt_dispatch, esto es porque todavia mi código sigue en fase de pruebas, y ademas que no se ejecuta la acción edit_selected inmediatamente, primero se muestra la pantalla, aqui es donde extraño un poco el ciclo de vida de JSF (Java Server Faces)… :(, también notar que la acción update_multiple esta programada para que no tome en cuenta los registros en blanco para realizar la actualización.

Otro detalle importante de recalcar es que estoy haciendo validaciones sobre si se seleccionaron registros en el servidor y no con javascript, bueno recuerden que estoy aprendiendo a usar rails y todavia no empiezo a ver como hacer esto mas dinamico con AJAX, así que sean pacientes 🙂

3.- Editando el formulario principal
Una vez configurados las rutas y el controlador, hay que agregar las acciones a los botones correspondientes, así pues mi archivo index.html.erb queda así:

   

Users catalog


<% if @users.blank? %>

The are no users yet!


<% else %>
<%= form_tag evt_dispatch_admin_users_path do %>
<%= button_tag 'Delete Selected', :value => "delete", :type => :submit, :confirm => 'Are you sure?' %>
<%= button_tag 'Edit Selected', :value => "edit", :type => :submit %>










<% @users.each do |user| %>











<% end %>
Username Name Last name Email Role Status
<%= check_box_tag "user_ids[]", user.id %> <%= user.username %> <%= user.name %> <%= user.last_name %> <%= user.email %> <%= @roles[user.role] %> <%= @status_desc[user.status.to_sym] %> <%= link_to 'Edit', edit_admin_user_path(user) %> <%= link_to 'Delete', admin_user_path(user), :method => :delete,
:confirm => 'Are you sure?' %>

<% end %>
<% end %>


<%= link_to 'New User', new_admin_user_path %>

Aquí como pueden ver uso los helpers button_tag y lo único que cambio es el “valor” del botón o lo que envia, al hacer clic a un botón se envia a la acción evt_dispatch en el controller y dependiendo de que botón se presionó entonces se ejecuta una acción.

4.- Crear vista para edición multiple
Por ultimo es necesario crear la vista para edición multiple, el archivo edit_selected.html.erb me quedó de la siguiente manera:

 
<%= form_for :user, :url => update_multiple_admin_users_path, :method => :put do |f| %>

    <% for user in @users %>

  • <%= hidden_field_tag "user_ids[]", user.id %>
    <%= user.username %>

  • <% end %>

<%= f.label :role %>
<%= f.select :role, User::roles.map{|role| [ role[1], role[0] ]}, :include_blank => true %>
<%= f.label :status %>
<%= f.select :status, User::status_desc.map{|role| [ role[1], role[0] ]}, :include_blank => true %>
<%= f.submit %>
<% end %>
<%= link_to 'Back', admin_users_path %>

Estoy usando el for para poder mostrar los elementos seleccionados para que el usuario pueda visualizar que elementos se está editando, y además estoy agregando campos en blanco para los elementos de tipo Select esto es porque quiero que los campos en blanco sean ignorados al momento de actualizar los registros. Tanto el rol como el estatus son obtenidos de un pequeño hash que agregué al modelo del usuario, esto es porque son valores predefinidos y es una manera de tener mas control sobre lo que se puede agregar en los campos.
En fin, espero les pueda servir este pequeño truco y lo puedan adaptar a sus necesidades, todavia no tengo nada entregable pero en cuanto lo tenga publicaré la ruta de mi proyecto en github para que puedan usar mi código si así lo desean. Hasta pronto.

Leave a Reply

Your email address will not be published. Required fields are marked *