#Charla sobre Rails para Lugmen - Copyleft dic 2010 Sergio A. Alonso @karancho #Hola a todos! #Introducción mas o menos profunda a Ruby on Rails #Este es un framework de desarrollo rápido de paginas. Incorpora las mejores ideas que se incluye en todo #framework moderno: testing, orm, persistencia, xhtml, mvc, etc. La diferencia es que es muy simple #Parafraseando a H. Simpson, es un artifundio mucho muy simple. #Comenzamos: nos paramos en cualquier parte, e iniciamos un proyecto nuevo rails new agenda #Entramos al proyecto cd agenda #Recomendado, iniciamos screen adentro, y git. Git ademas es muy piola para no tener que recurrir al viejo FTP screen git init . git config --global user.name "Sergio Alonso" git config --global user.email "sergio@eim.esc.edu.ar" git config --global color.ui "auto" #Cambiamos el tipo de base de datos que vamos a usar. Ejemplo: en development y en testing usamos SQLite. #En producción usamos algun motor mas potente, o usamos el cloud (amazon, heroku, etc) vim config/database.yml #Giteo git add . git commit -a -m "Primer commit" #Empezamos fácil: creamos modelo->migraciones, vista, controlador, y rutas, todo con un solo comando. Solo mencionamos #la clase modelo a utilizar, class Friend, que apunta a una tabla, que todavia no existe, llamada friends rails generate scaffold Friend name:string lastname:string bestfriend:boolean age:integer #Entre todas las cosas que se han creado, debemos prestar atención al modelo, guardado en app/models/friend.rb, y una #migración esperando ser corrida, en db/migrate #Esto genera 3 bases: development, testing y production rake db:migrate #Ok, ya tenemos las bases creadas, y un ABM que apunta a nuestra tabla friends. Creamos un server de pruebas rails server #Spliteamos en screen para tener el log del server como espejo retrovisor #Split en screen: Ctrl a S #Cambiar al otro buffer: Ctrl a Ctrl i #Creamos otra terminal dentro de screen (gracias Marteen!) con Ctrl a c #Mas informacion sobre screen: man screen o Ctrl a ? #Dejamos el logging del server, y creamos un amigo, Horacio lynx http://localhost:3000/friends #lynx es un viejo navegador de consola. si parece trabado, es que está esperando aceptar Cookies - Opción #Si miramos el log del server, podremos ver las inserciones sobre la base, las peticiones GET y POST, etc #Agregamos en el modelo algunas validaciones, en screen podemos hacer split vertical mediante Ctrl A | #y trasladarnos entre buffers mediante Ctrl a Ctrl i #Ejemplo de validaciones: #validates_presence_of :name #validates_uniquenes_of :dni (no en este caso) #validates_numericality_of :age #Compliquemos la cosa. Rails no es especial por lograr rapidamente un abm. Codelgniter, qCODO y otros frameworks de PHP #tambien lo hacen rápido. La diferencia es la curva de aprendizaje cuando queremos alterar las cosas, gracias a Ruby, un #lenguaje de sintaxis muy natural. #Recien habiamos creado un abm rápidamente mediante un generate scaffold (andamio). #Scaffold es discutido para enseñanza en Rails, porque según la comunidad, #atrae idiotas que quieren todo fácil. ================================================= #Ahora vamos mas despacio: fabriquemos Modelo, Vista, Controlador y Rutas, por separado. # Podemos empezar por cualquier parte. Empecemos por el modelo. Ctrl a c me fabrica una tercer consola rails generate model Phone phone:string friend_id:integer #Actualizamos base rake db:migrate #Establecemos relaciones entre las tablas friends y phones #Una amigo puede tener muchos telefonos (has_many :phones), de modo que lo aclaramos en el modelo vim app/models/friend.rb #En tanto que un telefono, pertenece univocamente a un amigo (belongs_to :friend) vim app/models/phone.rb #Esto funciona? Antes de sentarnos a codear, probemos el sistema de persistencia, para ver si es #coherente. #Hay muchas maneras, una es testear los modelos. Esto despliega unos fixtures sobre una copia #de la base develpment, llamada test #Uf, cuanto texto para algo tan simple rake test:units #Listo, pueden abrir los ojos #Otra forma de probar antes de codear: #Rails viene con un ORM llamado ActiveRecord. Y es capaz de usar a irb, un poligono de tiro #parecido a Python #Estamos en modo development. Estas pruebas no quedan en la base production rails console #Adentro de rails console, juguemos: #Que atributos tiene la clase Friend? Friend #Cuantos amigos tengo? Friend.all #Deberia aparecer el que hicimos durante el Scaffold :colorscheme borland unamigo = Friend.new unamigo.name = "Dante" unamigo.lastname = "Renda" unamigo.bestfriend = true unamigo.age = 36 unamigo.save #Que id le toco a mi amigo? Debería ser 2, si es que ya inserté otro amigo antes, durante la demostración #del scaffold unamigo.id telDante = Phone.new telDante.phone = "4309149" telDante.friend_id = 2 telDante.save #Es una relacion 1 a muchos, asi que agreguemos otro telefono otrotelDante = Phone.new otrotelDante.phone = "155072219" otrotelDante.friend_id = 2 otrotelDante.save #Revisemos. De quien es este telefono? otrotelDante.friend.name #Cuantos telefonos tiene Dante? unamigo.phones #Generemos ahora un listado de telefonos, solito, sin scaffoldear magicamente, donde figure #cada telefono y su dueño. #Necesito un controlador, que llamaré bienvenida. Cada cosa que hace un controlador se define en una acción #En este caso, la acción se llamara listado rails generate controller bienvenida listado #Editamos app/controllers/bienvenida_controller.rb y generamos una variable de instancia que contenga #todos los telefonos @telefonos = Phone.all #Toda accion, cuando termina su ejecución, llama a una vista asociada. En este caso, la vista asociada será #app/views/bienvenida/listado.html.erb #A ver si codeamos un poco, ya me estoy aburriendo

Bienvenida#listado

<% @telefonos.each do |x| %>

<%= x.phone %> <%= x.friend.name %>

<% end %> #Listidijillo, has would say my friend Flanders #Vamos ahora hasta http://localhost:3000/bienvenida/listado #Por cierto, esta combinacion Controlador -> Acción quedaria bien como pagina principal #Actualmente la pagina principal es una bienvenida de Rails, presente en http://localhost:3000 #Borremos la pagina de bienvenida rm public/index.html #Y apuntemos la raiz de la aplicación: vim config/routes.rb #Vamos bien? Guardemos los cambios en el repo local git add . git status git commit -a -m "ABM Friends y Listado de Telefonos listo" tig #Migraciones: para cuando necesito alterar el schema. Luego debo corregir vistas #Ejemplo, categorizo a mis amigos de acuerdo a su procedencia, o categoria: facultad, lugmen, #trabajo, idiotas, etc #Esta será una categoría de uno a muchos: un amigo puede figurar solo en una categoría, pero #en un categoría pueden figurar muchos amigos. #Como dice el viejo adagio: en una relación de 1 a muchos, la clave de los unos va del #lado de los muchos. # [ Amigos ] M ----- 1 [Categorias] #Comienzo fabricando una tabla categorias, con su modelo asociado rails generate model Category category:string #Reviso la migración que acabo de plantear (todavía no ha corrido) vim db/migrate/20101222131931_create_categories.rb #Algo util, es que puedo poblar ahora la tabla con datos. Recordemos que mantengo otras bases #ademas de development, llamadas test y production. Ambas se basan en la primera. #Y es aburrido ponerse a poblar las tres bases con los registros auxiliares. #En el momento del test o del deploy hacia un cloud, voy a tener que ponerme otra vez a #llenar Facultad, Lugmen, Trabajo, etc. Un embole. Rails se adscribe a un movimiento DRY #(Don't Repeat Yourself - No repitas) #Agrego entonces, en el momento de la creación, algunos valores: Category.create(:category => 'Facultad') Category.create(:category => 'Trabajo') Category.create(:category => 'Lugmen') Category.create(:category => 'Club de golf (eeeesa!)') Category.create(:category => 'Idiotas') #Sigamos #Le agrego a la tabla amigos un campo relación. Conviene que posea el nombre de la tabla #asociada, seguida de _id, asi Rails "conviene" los pasos automaticos. #En lugar de fastidiosos XML, en Rails se prefiere Convenir antes que Configurar. rails generate migration AddCategoryIdToFriends category_id:integer #Revisamos la migración vim db/migrate/20101222132255_add_category_id_to_friends.rb # Vaya, esta todo echo. Rails permite usar atajos para escribir código, si uno es capaz # de escribir el nombre de la migración de una forma descriptiva, en estilo CamelCase. # En este caso, usar el nombre AddCategoryIdToFriends me permitio dejar este archivo listo. # Ahora si, corremos las dos migraciones acumuladas: la creacion de categorias, y el # campo - clave ajena en amigos rake db:migrate #Y finalmente, formalizo la relación. Aviso a app/models/friend.rb belongs_to :category #Y en app/models/category.rb has_many :friends # Ahora viene la frutilla sobre el postre, incorporemos un