Bueno aquí me tienen de nuevo dando lata…
Hace tiempo puse un pequeño COMO de la instalación de Ruby+ Mongrel
Bueno pues vamos a hora a ver como hacer una pequeña aplicación integrando Ajax y la clase de Rico que viene integrado con la gema ajax_scaffold_generator
Manos a la obra …
Lo que intentaremos hacer integrarle un rol a un usuario…
Para esto creamos nuestra base de datos y unas tablas
Yo le llame sav a la base de datos y cada tabla se llama usuarios y rols respectivamente respetando la nomenclatura que indica ruby.
Pues creamos nuestra base de datos;
fvasquez@inf:~$ mysqladmin create sav
Ahora las tablas
Creamos un archivo y escribimos lo siguiente
fvasquez@inf:~$ nano tablas.sql
CREATE TABLE `rols` (
`rol` varchar(30) NOT NULL,
`descripcion` varchar(50) NOT NULL,
`id` int(11) NOT NULL auto_increment,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT=’Roles para Usuarios’ AUTO_INCREMENT=1;
CREATE TABLE `usuarios` (
`nombre` varchar(50) NOT NULL,
`apellido` varchar(50) NOT NULL,
`usuario` varchar(20) NOT NULL,
`password` varchar(60) NOT NULL default ”,
`rol_id` int(11) NOT NULL,
`id` int(11) NOT NULL auto_increment,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT=’Usuarios del sistema’ AUTO_INCREMENT=1
Ahora lo volcamos a la base de datos
fvasquez@inf:~$ sudo mysql < tablas.sql
Ya tenemos nuestras tablas….
Ahora vamos a actualizar nuestras gemas e instalar ajax_scaffold_generator
fvasquez@inf:~$ sudo gem update
fvasquez@inf:~$ sudo gem install ajax_scaffold_generator
Parece que todo va bien por aquí….
Ahora vamos a crear nuestra aplicación con rails
fvasquez@inf:~$ rails sav
fvasquez@inf:~$ cd sav
Editamos el archivo database.yml y lo dejamos como se muestra continuación
fvasquez@inf:~/sav$ nano config/database.yml
development:
adapter: mysql
database: sav
username: root
password:
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
database: sav
username: root
password:
socket: /var/run/mysqld/mysqld.sock
production:
adapter: mysql
database: sav
username: root
password:
socket: /var/run/mysqld/mysqld.sock
Ahora vamos a lo mas agradable.. que nos genere el codigo de la taba rols
fvasquez@inf:~/sav$ ruby script/generate ajax_scaffold Rol
Y eso es mas o menos todo, tendremos una aplicación funcionando con una visualización bastante buena, aunque faltaria por ejemplo validar campos entre otras cosas
Prendemos nuestro servidor para visualizar lo que tenemos
fvasquez@inf:~/sav$ ruby script/server mongrel -d
Vamos al navegador y ponemos lo siguiente
http://localhost:3000/rols/
Juguemos un rato con esta aplicación y agreguemos unos cuantos registros y vamos al siguiente paso….
Ahora hacemos el scaffold para la tabla usuarios
fvasquez@inf:~/sav$ ruby script/generate ajax_scaffold Usuario
Vamos al navegador y ponemos lo siguiente
http://localhost:3000/usuarios/
Tratemos de agregar algún usuario y al parecer todo esta bien… Pero no… si nos damos cuenta tenemos un campo el cual no aparece y que es el de rol_id, y no aparece porque es un campo numérico y al contener solo números parecería no relevante pero vamos a hacer que lo sea y a también a desplegarlo en la tabla…
Queremos que en el campo rol_id se almacene el id de la tabla rols pero en la visualizacion nos muestre el campo rol en el select
Esto se pone interesante…
Bien pues manos a la obra…
Primero debemos ver es como va a ser la relación
Un usuario tiene un único rol y un mismo rol puede pertenecer a varios usuarios.
Para esto editamos los archivos /models/rol.rb y /models/usuario.rb y los dejamos como se muestra a continuación
fvasquez@inf:~/sav$ nano app/models/rol.rb
require ‘ajax_scaffold’
class Rol < ActiveRecord::Base
has_many :usuarios
end
fvasquez@inf:~/sav$ nano app/models/usuario.rb
require ‘ajax_scaffold’
class Usuario < ActiveRecord::Base
belongs_to :rol, :foreign_key => “rol_id”
end
Las declaraciones anteriores nos permiten generar nuevos métodos y caminar atraves de estas relaciones desde ruby.
Por ejemplo, desde un objeto @usuario se puede averiguar que rol es el que tiene por medio de @usuario.rol.rol
Ahora necesitamos agregar un campo select que nos permita seleccionar el rol que tiene un usuario…
Para esto editamos el archivo _form.rhtml y lo dejamos como se muestra
fvasquez@inf:~/sav$ nano app/views/usuarios/_form.rhtml
<%= text_field ‘usuario’, ‘nombre’ , {:class=>”text-input”} %>
<%= text_field ‘usuario’, ‘apellido’ , {:class=>”text-input”} %>
<%= text_field ‘usuario’, ‘usuario’ , {:class=>”text-input”} %>
<%= password_field ‘usuario’, ‘password’ , {:class=>”text-input”} %>
<%= select “usuario”, “rol_id”, @rols %>
Si nos fijamos lo único que agregamos fue esto:
<%= select “usuario”, “rol_id”, @rols %>
Lo interesante de aqui es el select que llama al objeto usuario y en el campo rol_id se va a almacenar la seleccion que se escoja de la lista que se tiene en el objeto @rols.
Si corremos la aplicación nuevamente aparecerá el campo pero vacio, esto es porque aun el objeto @rols aun no tiene elementos para que esto suceda nos vamos a modificar el controlador a indicar que elementos tendrá el objeto @rols
Editamos el archivo usuarios_controller.rb
fvasquez@inf:~/sav$ nano app/controllers/usuario_controller.rb
Y dejamos la definición new como se muestra
def new
@usuario = Usuario.new
@rols = Rol.find_all.collect {|t|[t.rol, t.id] }
@successful = true
return render(:action => ‘new.rjs’) if request.xhr?
# Javascript disabled fallback
if @successful
@options = { :action => “create” }
render :partial => “new_edit”, :layout => true
else
return_to_main
end
end
Lo que insertamos fue esto:
@rols = Rol.find_all.collect {|t|[t.rol, t.id] }
Esto quiere decir que el objeto @rols va a ser una colección de los elementos de un arreglo que regresa el método find_all.collect de la clase Rol los cuales son rol e id que se extraen de la tabla rols.
Estos son los elementos de visualización para nuestro campo select de captura, visualizaremos el elemento rol pero ingresaremos en nuestra tabla su id
Bien pues capturemos algunos elementos nuevos en la tabla usuarios a través de nuestra aplicación
http://localhost:3000/usuarios/
Pero que sucede si queremos editar algún registro… no podemos y esto es porque tanto la creación de nuevos registros como la edición utilizan los mismos principios así que en el mismo controller del usuario agregamos lo siguiente el la definición de edit
fvasquez@inf:~/sav$ nano app/controllers/usuario_controller.rb
def edit
begin
@usuario = Usuario.find(params[:id])
@successful = !@usuario.nil?
@rols = Rol.find_all.collect {|t|[t.rol, t.id] }
rescue
flash[:error], @successful = $!.to_s, false
end
return render(:action => ‘edit.rjs’) if request.xhr?
if @successful
@options = { :scaffold_id => params[:scaffold_id], :action => “update”, :id => params[:id] }
render :partial => ‘new_edit’, :layout => true
else
return_to_main
end
end
Si nos damos cuenta solo ingresamos la misma linea que en el método new
@rols = Rol.find_all.collect {|t|[t.rol, t.id] }
Ahora vamos a ejecutar la aplicación y parecer ya esta funcionando el proceso de captura y edición de usuarios
http://localhost:3000/usuarios/
Pero no podemos ver en la tabla el campo rol_id….
Bien pues manos a la obra….
Lo que debemos hacer es indicar en nuestro modelo que campos son los que queremos ver de nuestra tabla y en el caso de rol_id evaluar mediante las relaciones que hicimos anteriormente que campo es el que queremos visualizar de la tabla rol, en vez del índice..
Para esto editamos el archivo usuario.rb y lo dejamos como se muestra a continuación
fvasquez@inf:~/sav$ nano app/models/usuario.rb
require ‘ajax_scaffold’
class Usuario < ActiveRecord::Base
belongs_to :rol, :foreign_key => “rol_id”
@scaffold_columns = [
AjaxScaffold::ScaffoldColumn.new(self, { :name => “nombre”}),
AjaxScaffold::ScaffoldColumn.new(self, { :name => “apellido”}),
AjaxScaffold::ScaffoldColumn.new(self, { :name => “usuario”}),
AjaxScaffold::ScaffoldColumn.new(self, { :name => “password”}),
AjaxScaffold::ScaffoldColumn.new(self, { :name => “rol_id”,
:eval => “usuario.rol.rol”, :label => “Rol”}),
]
end
Con esto indicamos que en lugar de ponernos el numero correspondiente en el campo rol.id nos evalué y visualice el campo rol correspondiente de la tabla rols…
Y ahora a ver de nuevo la aplicación
http://localhost:3000/usuarios/
Bueno hasta aquí le vamos a dejar por ahora….
Pronto continuaremos utilizando Ruby on rails
Cualquier comentario es bien recibido…..
Faustino Vasquez Limon
Universidad Xochicalco Campus Tijuana
Linux User : “Agrega Espacio a tu disco Duro Quitando Windows”