Ejemplo de Relacion HABTM con Checkboxes RoR

0
480
.

Hola a todos por aqui…

Ahora vamos a realizar una actualizacion al “COMO Aplic. RoR con check_boxs para una relacion N:N” documento que tenemos aqui mismo dandole una nueva forma de desarrollo con menos pasos y ayudandonos de algunos elementos que mismo framework nos proporciona:

Asi que manos a la obra

 
Como siempre creamos nuestro proyecto para que funcione con mysql

 


fvasquez@fvasquez:~$ rails -d mysql escuela


 Creamos nuestra base de datos dentro de mysql


fvasquez@fvasquez:~$ sudo mysqladmin create escuela -p


Y editamos nuestro archivo de configuracion para que quede de la siguiente forma


 fvasquez@fvasquez:~/escuela$ nano /config/database.yml

# MySQL.  Versions 4.1 and 5.0 are recommended.
#
# Install the MySQL driver:
#   gem install mysql
# On Mac OS X:
#   sudo gem install mysql — –with-mysql-dir=/usr/local/mysql
# On Mac OS X Leopard:
#   sudo env ARCHFLAGS=”-arch i386″ gem install mysql — –with-mysql-config=/usr/local/mysql/bin/mysql_config
#       This sets the ARCHFLAGS environment variable to your native architecture
# On Windows:
#   gem install mysql
#       Choose the win32 build.
#       Install MySQL and put its /bin directory on your path.
#
# And be sure to use new-style password hashing:
#   http://dev.mysql.com/doc/refman/5.0/en/old-client.html
development:
  adapter: mysql
  encoding: utf8
  database: escuela
  username: root
  password: 123456
  socket: /var/run/mysqld/mysqld.sock

# Warning: The database defined as “test” will be erased and
# re-generated from your development database when you run “rake”.
# Do not set this db to the same as development or production.
test:
  adapter: mysql
  encoding: utf8
  database: escuela
  username: root
  password: 123456
  socket: /var/run/mysqld/mysqld.sock

production:
  adapter: mysql
  encoding: utf8
  database: escuela
  username: root
  password: 123456
  socket: /var/run/mysqld/mysqld.sock


Ahora nos bajamos el plugin resource controller de jamesgoolick


fvasquez@fvasquez:~/escuela$ svn export http://svn.jamesgolick.com/resource_controller/tags/stable vendor/plugins/resource_controller


Una vez que tengamos lo anterior analizemos un poco lo que pretendemos hacer…

Necesitamos crear el siguiente modelo de relacion en este caso llamado HABTM (has_and_belongs_to_many), para dos tablas relacionadas de muchos a muchos, para eso nos vamos a ayudar de una tercera la cual nos permitira almacenar los indices de cada una de las otras dos tablas con la relacion corres pondiente.


.

Y en este caso en lugar de crear las tablas para nuestro proyecto a pincel, vamos a crear los archivos de migracion de nuestro proyecto a traves del generador scaffold_resource.


fvasquez@fvasquez:~/escuela$  ./script/generate scaffold_resource Alumno alumno:string

fvasquez@fvasquez:~/escuela$  ./script/generate scaffol_resource Grupo grupo:string


Solo nos faltaria crear el archivo de migracion para el modelo alumnos_grupos asi que lo haremos de la siguiente forma


fvasquez@fvasquez:~/escuela$ ./script/generate migration alumnos_grupos


Y esto en mi caso me crea el archivo /db/migrate/20080722160220_alumnos_grupos.rb (la numeracion cambiara obviamente en tu proyecto)

Pues bien este docto lo editamos y lo dejamos como se muestra a continuacion


fvasquez@fvasquez:~/escuela$  nano /db/migrate/20080722160220_alumnos_grupos.rb

class AlumnosGrupos < ActiveRecord::Migration
  def self.up
      create_table :alumnos_grupos, :id => false do |t|
      t.string :alumno_id
      t.string :grupo_id
      end
 end

 def self.down
  drop_table :alumnos_grupos
 end
end

 

 Si nos damos cuenta este archivo de migracion no creara id para la tabla y solo contendra los campos indices alumno_id y grupo_id 


Una vez creado todo lo anterior migramos nuestros archivos a la base de datos


fvasquez@fvasquez:~/escuela$  rake db:migrate


Con eso ya tendremos nuestras tablas creadas y listas….

Ahora viene lo bueno….

Como nuestro proyecto contiene una relacion de muchos a muchos en ambos sentidos tenemos que crear el modelo de relacion..
Asi que modificamos los siguientes archivos y los dejamos como se muestra a continuacion


fvasquez@fvasquez:~/escuela$ nano /app/models/alumno.rb

class Alumno < ActiveRecord::Base
has_and_belongs_to_many :grupos
end


fvasquez@fvasquez:~/escuela$ nano /app/models/grupo.rb

class Grupo < ActiveRecord::Base
has_and_belongs_to_many :alumnos
end

 


 Ya con el modelo de relacion establecida podemos empezar a modificar nuestras vistas para capturar lo datos y visualizarlos como necesitamos…
Editamos los siguientes archivos y los dejamos como se muestra a continuacion, la parte que se encuentra en letras mas remarcadas sera lo que hay que modificar…


fvasquez@fvasquez:~/escuela$  nano /app/views/alumnos/_form.html.erb


  Alumno:
  <%= f.text_field :alumno %>

<% for g in Grupo.find(:all) %>
 

  <%= check_box_tag “alumno[grupo_ids][]”, g.id ,@alumno.grupos.include?(g) %>
  <%= g.grupo %>
 

<% end %>


fvasquez@fvasquez:~/escuela$ nano /app/views/alumnos/index.html.erb

Listing Alumnos

 

   

 

  <%- @alumnos.each do |alumno|%>
     

     

       

   

   

     

     

   
  <% end %>

Alumno
<%=h alumno.alumno %>
       <%for g in alumno.grupos%>
           

               <%=h g.grupo %>
           

        <%end%>
       

<%=link_to ‘Show’, object_url(alumno) %>
      <%=link_to ‘Edit’, edit_object_url(alumno) %>
      <%=link_to ‘Destroy’, object_url(alumno), :confirm => ‘Are you sure?’, :method => :delete %>

<%= link_to ‘New Alumno’, new_object_url %>


fvasquez@fvasquez:~/escuela$ nano /app/views/alumnos/show.form.html.erb

  Alumno:<%=h @alumno.alumno %>

       <%for g in @alumno.grupos%>
         

                <%=h g.grupo %>
             

         <%end%>

<%= link_to ‘Edit’, edit_object_url %>
|
<%= link_to ‘Back’, collection_url %>


fvasquez@fvasquez:~/escuela$ nano /app/controllers/views/alumnos_controller.rb

class AlumnosController < ResourceController::Base
    def update
        params[:alumno][:grupo_ids] ||= []
        @alumno = Alumno.find(params[:id])
        if @alumno.update_attributes(params[:alumno])
           flash[:notice] = ‘alumno was successfully updated.’
            redirect_to :action => ‘show’, :id => @alumno
        else
          render :action => ‘edit’
        end
    end
end


Aqui unas capturas de las pantallas

Pantalla de captura para grupos

 1

 

Listado de Grupos Capturados

 .

 

Pantalla de Captura de Alumnos

 .

 

Seleccion de multiples grupos por medio de checkbox

 .

 

Listado para todos los alumnos capturados

.

 

Listado de un alumno los datos de un alumno especifico

.

 

Como siempre espero que estos documentos les sean de utilidad

 Atte Faustino Vasquez Limon

Linux User

LEAVE A REPLY

Please enter your comment!
Please enter your name here