Curso de Ruby on Rails – Parte 2

4 Comments

Voy a seguir esta “saga” de como hacer una aplicación muy sencilla desde 0 con Ruby on Rails. En el post anterior instalamos el entorno y creamos nuestro “Hello World!”, incluso lo subimos a Heroku para que nuestros amigos lo pudieran ver.

Pero nos apetece que nuestra aplicación tenga más “chicha”, verdad? algo que justifique el uso de RoR y no simplemente HTML plano. Pues vamos a crear algún scaffold que más adelante uniremos entre sí.

El primero que crearemos será el de los alumnos. Para ello, en una consola y estando en el directorio de nuestro proyecto, ponemos lo siguiente:

rails generate scaffold student first_name:string last_name:string

Le estamos diciendo que cree un scaffold llamado student con 2 campos string: first_name y last_name. De momento no necesitamos más, ya que Rails internamente ya nos meterá un id numérico, además de la fecha de creación y de última modificación (que puedes quitar si quieres). Si necesitamos más campos después, ya los añadiremos.

Si nos vamos a nuestro proyecto vemos que nos ha creado varias cosas: Un controlador, un helper, un modelo y una carpeta con varias vistas (las del CRUD). Como vemos, algunas cosas nos las ha pasado a plural, ya que Rails detecta los singulares y los plurales y te los pone de una u otra forma en función del tipo de fichero que esté creando (cuidado con esto si hacemos un scaffold de cosas como “person”, que su plural es “people” no “persons” y Rails lo sabe, que es muuuuy listo). Y ahora vamos a ver que tal nuestro CRUD y para eso entramos a http://localhost:3000/students. Pero… que pasa? no funciona!!! Lo primero, te has acordado de levantar el servidor? Lo tienes levantado y te sigue sin funcionar? Normal, has creado el modelo (fichero db/xxxxx_create_students.rb) pero no lo has migrado a la BD, vamos que tu BD no sabe que hay estudiantes ni los campos que tienen. Para hacer que nuestra BD se entere, vamos a hacer lo siguiente en la consola:

rake db:migrate

Ahora ya sí que nos debería de funcionar. Ya tenemos nuestro CRUD funcionando, podemos crear, borrar, consultar y actualizar a cualquier alumno. Que fácil, ¿verdad? Esto lo haría hasta un mono!

Hacemos lo mismo con las asignaturas en las que se matricularán los alumnos:

rails generate scaffold subject name:string
rake db:migrate

Podríamos haber hecho un sólo db:migrate para los 2 scaffold, pero aquí vamos paso a paso :)

Ahora vamos a meterle algún requisito a nuestro modelo, como que todo alumno tiene que tener obligatoriamente un first_name y que una asignatura debe tener al menos nombre, porque sino vaya asignatura…

Para ello, nos vamos al fichero app/models/student.rb y ponemos los siguiente:
Vemos que es muy fácil decirle qué campos tienen que ser obligatorios. Probadlo y ya veréis que funciona ;) No hago el del otro scaffold porque es igual y vosotros sois chic@s listos!

Ahora creemos que estaría bien enlazar esta nueva funcionalidad a nuestra página de inicio, porque es un rollo tener que andar jugando con la URL del navegador… Para ello nos vamos al fichero app/views/welcome/index.html.erb que definimos ayer, y ponemos los 2 enlaces a los scaffolds recién creados:

Qué cómodo, ¿verdad? No tenemos ni que saber donde está el controlador, simplemente le decimos el texto que queremos en el enlace y luego rails sabe donde redirigir cuando pongamos students_path.

Ahora en vez de avanzar, vamos a mirar un poco el código que se nos ha generado, ya que en algún momento tendremos que cambiarlo. Empezaremos por uno de los controladores, el del student para seguir un poco con el hilo del resto del post. Lo primero que vemos es una operación llamada “index”
Vemos que lo primero que genera es una variable de instancia con todos los alumnos que recoge de Student.all. Si queremos ver lo que hace esto internamente podemos ir a la ventana de la consola y veremos las sentencias SQL que se ejecutan. Después vemos algo de formatos… que raro parece eso… pues si nuestra aplicación la queremos en html nada más no sirve para mucho, pero y si queremos por ejemplo ver nuestra aplicación en xml? Pues Rails te la convierte automáticamente! Si accedemos a http://localhost:3000/students.xml esto nos devolverá la página pero en formato XML. Podríamos también usar json por ejemplo, añadiendo a la lista de formatos lo siguiente:

format.json { render :json => @students }

Cuidado, esto vale para la operación show, en otras igual hay que poner student (en singular). Fíjate en las otras de esa misma operación.

Vamos a ver otra, y ya el resto para vosotros:

Quería ver otra distinta a index porque es importante ver el detalle del params. Cuando vamos a algún controlador, Rails internamente nos ha creado el array llamado params con todos los parámetros de la petición. En este caso ha cogido la URL que había en el link de “show”, lo ha partido en trozos y lo ha metido en params. Luego con eso podemos acceder al :id (que si te fijas aparece en la URL del enlace) del alumno sobre el cuál queremos consultar sus datos.

Ahora vamos con las vistas. Si nos fijamos, el formulario de edición y creación de un alumno es igual. Para no repetir código, en RoR tenemos la opción de crear lo que se llaman “Partials”, que es sacar una parte de código a otro fichero y luego enlazarlo desde donde queramos. El nombre de estos partials tienen que empezar por el caracter “_”. En nuestro caso vemos que el directorio “views/students” tiene un _form.html.erb con los datos del formulario de edición y creación de usuario y que luego por ejemplo en new.html.erb tenemos un “render ‘form’ ” que lo que hace es colocar el partial form en ese punto. Rails automáticamente sabe que si le decimos “form” tiene que buscar en la carpeta actual un fichero con nombre _form.html.erb. Podríamos sacarlo a otra carpeta si creemos que lo podemos necesitar en otro lado y acceder con “render ‘otra_carpeta/form’ “.

Otro código que me gustaría resaltar es cómo trabaja Rails con las variables de instancia que hemos hablado antes en la operación “index” del controlador. Si por ejemplo nos vamos al fichero views/students/show.html.erb vemos lo siguiente:

Lo primero vemos un “notice”, que lo veremos más adelante, pero que sirve para sacar textos informativos al usuario. Después ya se ve como se accede a la variable de instancia para recoger los valores, ya que desde la vista la tenemos accesible sin problemas. Otra vez, ¿qué sencillo verdad?
A muchos no les resultará desconocido, pero para los que sí, la diferencia entre código Ruby metido entre <%= %> y <% %> es que cuando está el igual significa que el resultado de la operación se añadirá al código html y sin el igual es para realizar operaciones sin resultado visible (por ejemplo, sentencias IFs, o realizar una operación que usaremos más adelante o cosas así)

Con esto ya tenemos para jugar un poco. Para próximos post dejo los layout (templates de la aplicación), cómo hacer que se relacionen alumnos y asignaturas, y cosas así que nos harán la aplicación un poco más bonita y útil.

Si lo quieres subir a Heroku para que tus amigos estén más orgullosos de ti aún, ya sabes como se hace!

Curso de Ruby on Rails – Parte 1

4 Comments

Desde el lunes hasta ayer he estado dando un curso de 2 horas diarias en Madrid On Rails impartido por Raimond García de Ruby on Rails (aka RoR). El curso ha sido muy introductorio, dándo lo básico tanto de Ruby como de Rails, con la idea de que luego cada uno vaya profundizando. He de decir que pensaba que iba a ser algo más avanzado el curso, no tan tan introductorio, pero creo que al final me ha venido mejor que sea así. Además me ha gustado como Raimond ha llevado el curso, centrándose en que codificáramos que es como realmente se aprende y resolviendo las dudas que pudiéramos tener.

Mi idea en estos post es ir poniendo lo que hemos ido viendo para guardarme un backup ya que mi memoria es limitada y si le sirve a alguien más pues perfecto! Lo iré haciendo por capítulos para que no quede muy largo y los que me salgan, 2, 3 o 15 (espero que no, que aburrimiento!).

Lo primero ha sido la instalación del entorno. Voy a poner sólo el de Mac, que es el que he utilizado. Tengo más información sobre instalaciones en otros sistemas operativos, con lo que si alguien la quiere, que la pida en los comentarios. Toda esta información está sacada del correo que nos envió Raimond a todos los participantes, así que el mérito a él :)

Librerias basicas
    Apple Xcode Developer Tools (versión 3.2 o superior)
Ruby
    sudo port install ruby
Gems
    sudo gem update --system
    sudo gem uninstall rubygems-update
Sqlite3
    sudo port upgrade sqlite3
    sudo gem install sqlite3-ruby
Rails
    sudo gem install rails
Rspec
    sudo gem install rspec
    sudo gem install diff-lcs
Git
    sudo port install git-core
    Crear una cuenta en github.com
Comprobar
    rails -v	(deberia ser Rails 3.0.3 a día de hoy)

Una vez que tenemos ya instalado lo que necesitamos, vamos a hacer algo en unos minutos con lo que ya podremos empezar a jugar. Por ejemplo voy a hacer una aplicación para una academia donde tendremos por un lado alumnos, asignaturas, y matrículas de los alumnos en las asignaturas. Muy sencillo, sin lógica practicamente ninguna, un CRUD de toda la vida.

Para ello, en un terminal, nos ponemos en el directorio que queramos tener nuestra aplicación, y ejecutamos lo siguiente:

rails new MiAcademia

donde MiAcademia es el nombre que queremos darle a la aplicación. Al ejecutar esto nos creará una carpeta llamada igual que la aplicación y dentro de esta tendremos un esqueleto de nuestra aplicación con un montón de ficheros y carpetas.

Para que no se nos olvide, lo primero que vamos a hacer es levantar el servidor para ver que todo está correcto. Para ello, desde el terminal, entramos en el directorio MiAcademia que hemos creado y desde ahí ejecutamos:

rails server

Para ver si todo está bien, entramos en un navegador, vamos a http://localhost:3000 y veremos una pantalla donde Rails nos da la bienvenida y una guía mínima de cuales pueden ser los siguientes pasos. Esa página que vemos es public/index.html. Como no la queremos para nada, la borramos, y ahora vamos a crear nuestra página de bienvenida.

rails generate controller welcome index

¿Qué significa esto? Estamos creando un controlador llamado “welcome” y una operación llamada “index”. Si vamos a nuestro directorio del proyecto, veremos que se nos han creado varios archivos: app/controllers/welcome_controller.rb, app/helpers/welcome_helper.rb y app/views/welcome/index.html.erb. Es decir, se nos ha creado nuestro controlador de bienvenida, un helper (ya veremos para que sirve), y nuestra vista. Es decir, que si en el navegador ponemos http://localhost:3000/welcome/index deberíamos poder ver nuestra página index. Vamos a modificarla para que aparezca otra cosa distinta a la página que se crea por defecto. Podemos poner algo como lo siguiente:

<h1>Bienvenido a nuestra academia</h1>
<p>Pronto tendremos más información</p>

Nada original, pero de momento no tenemos mucha más información que poner.

Pero queda un poco feo tener que poner esa URL tan larga, ¿verdad? Vamos a tratar de acortarla. Para ello editamos el fichero config/routes.rb. Ahí vemos que hay una línea que pone “get ‘welcome/index’”. Quitamos esa línea y la cambiamos por la referencia a nuestra página de bienvenida, poniendo lo siguiente: root :to

root :to => "welcome#index"

Y si ahora ponemos en el navegador http://localhost:3000 nada más, debería de salirnos nuestra página de bienvenida (si hemos borrado la que está en public/index.html como hemos dicho antes).

Pero ahora nos gustaría que nuestros amigos pudieran ver nuestro pedazo de trabajo, no? Pues vamos a hacerlo en Heroku (donde previamente tendremos que habernos creado una cuenta accediendo a la página) que es un servicio muy cómodo y gratuito (si usamos lo básico) con la ayuda de Git, que ya tenemos instalado. Para empezar a trabajar con Heroku, lo primero instalarnos la gema:

sudo gem install heroku

Y ya podemos ponernos a guardarlo en el repositorio de git y a publicarlo en heroku. Estando en el directorio principal del proyecto, ponemos lo siguiente en el terminal:

git init
git add .
git commit -m "Mi primera aplicacion con rails"
heroku create MiAcademia-[MI_NOMBRE_DE_USUARIO]
git push heroku master
heroku rake db:migrate

¿Qué significa todo esto? Primero inicializamos el repositorio, después añadimos todos los ficheros del directorio actual, para a continuación hacer el commit en nuestro repositorio local con un comentario. Una vez hecho esto, creamos en heroku nuestra aplicación (cambiar [MI_NOMBRE_DE_USUARIO por lo que sea, de cara a no entrar en conflictos), hacemos el push (igual que el commit, pero hacia el repositorio "en la nube") donde le indicamos que queremos meterlo en la rama "master" y por último le decimos que nos exporte la base de datos que tenemos también a heroku.

Una vez hecho esto, y si no tenemos ningún problema, deberíamos poder ir a http://miacademia-[MI_NOMBRE_DE_USUARIO].heroku.com y ver la aplicación. Ahora ya podemos enviársela a nuestros amigos para que vean lo que hacemos en 10 min :)

Creo que esto ya ha quedado demasiado largo. Las cosas más complejas para el siguiente post que escribiré a lo largo del día de hoy o quizás mañana.

Primeros códigos en Ruby

8 Comments

Desde hace unos días estoy dedicando algunos ratos a aprender Ruby, y que mejor que Ruby koans para empezar. Se basa en ir pasando algunas “pruebas” sobre diferentes temas (Constantes, funciones, bloques, etc) de Ruby con lo que vas aprendiendo como si fuera un juego.

El tema se va complicando poco a poco hasta que tienes que empezar a desarrollar y no sólo rellenar huecos. En ese punto estoy y por eso me he decidido a poner mi primer código para que me deis palos como si fueran gratis (que lo son) y como si no me tuvierais ningún respeto (que tampoco). La primera crítica imagino que vendrá por el naming pero lo se, soy un inútil con el naming en inglés. Y sí, podría hacerlo en español pero como los test están en ingles como que no mola hacer un spanglish (los famosos getNombre de java…)

El enunciado del problema resuelto (resumido) es el siguiente:

Es un juego de dados en el que se tiran 5 (yo lo he extendido a que se puedan tirar más dados) y se suman sus puntuaciones. Para calcular las puntuaciones se hace de la siguiente manera:

* Si salen 3 unos se suma 1000 puntos.

* Si salen 3 de cualquier otro se suman 100 * X, donde X es el número que se repite (ej, 3 doses son 200 puntos)

* Un uno que no esté dentro de un grupo de 3 suma 100 puntos (ej, si me salen 4 unos, son 1100, y 2 unos son 200)

* Un cinco que no esté dentro de un grupo de 3 suma 50 puntos

* Todo lo demás son 0 puntos

El código lo he intentado incrustar aquí pero no puedo instalar el plugin para Gist y no se como ponerlo en condiciones, así que os pongo el enlace al código en Gist:

https://gist.github.com/736614

Se aceptan (y se ruega) las críticas.

EDITO: Me parece bien la propuesta de Alberto de hacer los comentarios sobre el propio código, así que dejad ahí vuestras críticas a ver si entre todos hacemos un código decente :)