Category Archives: Ruby

Ruby on Rails, ¿se acabó lo que se daba?

Hace 3 años se publicó lo que fue la primera versión de un increíble framework para el desarrollo Web en un lenguaje de script no muy conocido, Ruby. Este framework era Ruby On Rails, y comenzó la revolución.

Desde entonces, en los dos años siguientes el tema de moda en la programación Web era lo cool que era RoR, que molaba mogollón, que era la hostia, que viva la madre que lo parió, y esas cosas. Incluso el año pasado me dio por probarlo a ver si realmente merecía la pena. Después de probar algunas de sus características lo dejé por dos razones, (1) ruby me parece parecía un lenguaje de script apestoso (yo lo veo como una mezcla de ada y perl, los cuales tienen unos puntos de vista totalmente opuestos!, ¡eso no se hace!), (2) ninguna de sus características es algo revolucionario, sí, son curiosas y chocan la primera vez, pero nada que no se puede hacer en otro lenguaje (en una tarde te programas la característica X que necesitas).

Últimamente se ha ido tranquilizando la cosa y apenas se hablaba ya de Rails, o al menos no tanto. Y hace un mes, a raíz de este post, empezaron las críticas sin parar hacia éste. Famosa es ya la historia de Twitter, aplicación escrita en RoR, que cuando alcanzó su éxito y comenzó su uso intensivo, estaba más tiempo caída que online (exagerando las cosas claro, pero era muy lenta y con bastantes caídas) y a partir de ésto se atacaba a rails criticando su falta de eficiencia y escalabilidad.

En mi opinión todo se está exagerando, simplemente la moda de Ruby On Rails ha pasado (2 años creo que es ya más que suficiente), lo cual no quiere decir que vaya a desaparecer, pero posiblemente significa que no crecerá mucho más, y dado que en el ámbito empresarial no es que haya entrado muy fuerte (principalmente debido a una falta de soporte o entidad detrás del framework, a diferencia de, por ejemplo, GWT o apestosas tecnologías Java en general), esto significa que la caída ha comenzado y no hay quien la pare.

Si hace un año hubiese dicho que Rails es una mierda, la gente me hubiese escupido, pegado una paliza, Google no me indexaría, Microsoft me mandaría bindous con cada telepizza y los teletubbies me dedicarían una canción. Ahora, una vez que ha pasado la moda, ya se permite tocar al intocable, y quien quiera, puede decir lo que le plazca. Ves que bien. Por mi parte, cuando tenga que realizar una aplicación Web en el futuro, rails será una de mis últimas primeras opciones, puesto aunque que por alternativas, no será.

HowTo: Integrando Rails con apache

railsApache.pngBueno, como dije en el anterior post, voy a explicar como integrar Rails con Apache, para que sea éste nuestro servidor Web. El servidor de Rails WEBrick (ejecutando script/server en el directorio de nuestra aplicación de Rails) cumple su función, sobre todo es útil para el desarrollo, pues muestra mucha información. Pero para un entorno real, no puede competir con un servidor web “de los de verdad” (estaría bien respaldar ésto con números, para otro día que me aburra…). Otra opción sería usar Rails con lighttpd, ésto lo he visto mucho por la red, y parece dar buenos resultados, pero como Apache es mucho Apache, prefiero usarlo :P.

Seguiré desde el HowTo anterior, es decir, tenemos una aplicación básica en ~/dev/rails la cual al final de este tutorial será servida a los clientes mediante apache. Supongo que estamos usando Ubuntu Dapper, para otra distro sería todo perfectamente aplicable, pero habría que cambiar, posiblemente, algunos de los binarios/directorios/archivos/nombres_de_paquetes por otros ligeramente diferentes. Intentaré ir explicando las cosas de la forma más generica posible… ok, entonces ¿qué necesitamos para poder servir aplicaciones RoR con apache?

  • Mod_rewrite (para apache)
  • Mod_fcgid (para apache)
  • fcgid en nuestro sistema
  • Modulo fcgid para ruby
  • Configurar apache, añadiendo un virtualhost (o un Directory + Alias)

Vayamos por partes, como dijo Jack el destripador. Mod_rewrite lo tendrás casi 100% seguro, a no ser que hayas compilado apache indicandole que no quieres ese modulo. ¿Cómo sabemos que lo tenemos?

$ /usr/sbin/apache2 -l # [el binario de apache] -l
Compiled in modules:
core.c
(…)
mod_alias.c
mod_so.c
$ ls /etc/apache2/mods-enabled/ # aquí aparecerán los módulos activos

Debe de salir en uno de esos dos comandos, si lo tienes instalado de los repositorios de ubuntu, saldrá en mods-enabled ;).

Mod_fcgid para apache, ok. Instalemoslo o si eres un autentico macho ibérico que compila todo, compila tu apache con este modulo!. Para el resto de mortales, simplemente esto:

$ sudo aptitude install libapache2-mod-fcgid
$ sudo /etc/init.d/apache2 force-reload
$ more /etc/apache2/mods-enabled/fcgid.conf # ahora tendremos estos dos ficheros, este

AddHandler fcgid-script .fcgi
SocketPath /var/lib/apache2/fcgid/sock

$ more /etc/apache2/mods-enabled/fcgid.load # y este!
LoadModule fcgid_module /usr/lib/apache2/modules/mod_fcgid.so

Ahora instalemos fcgi en nuestro sistema como librería compartida, podemos hacer un aptitude search fcgi para ver paquetes candidatos, en el caso de Ubuntu Dapper, simplemente:

$ sudo aptitude install libfcgi0

Ahora solo nos queda por instalar el modulo fcgi para ruby, para ello hacemos un:

$ sudo aptitude install libfcgi-ruby1.8 # o la que nos corresponda

Ahora hagamos la prueba definitiva, para saber si todo va bien:

$ irb
irb(main):001:0> require ‘fcgi.so’
=> true
irb(main):002:0> require ‘fcgi’
=> true

Muy bien!, ya tenemos todo preparado, ahora configuremos apache!. Haré la configuración con un Virtualhost, pues lo veo más cómodo (pero se podría hacer también con un “Directory” más un alias). Añadimos a la configuración de apache lo siguiente:

$ sudo vi /etc/apache2/sites-available/default # en dapper, sería en este fichero


ServerName rails
DocumentRoot /home/blaxter/dev/rails/public/
ErrorLog /home/blaxter/dev/rails/log/apache.log

Options ExecCGI +FollowSymLinks
AllowOverride all
Allow from all
Order allow,deny



$ sudo vi /etc/hosts # añadimos un linea como esto:
127.0.0.1 rails
$ sudo /etc/init.d/apache2 force-reload # reiniciamos apache

Debes cambiar /home/blaxter/dev/rails por la ruta de tu aplicación rails!.

Ahora debemos hacer un par de cosas antes de dejar todo listo. Primero borrar las sesiones actuales

$ cd ~/dev/rails # dir de nuestra aplicación
$ rm tmp/sessions/* # es importante hacer esto, hazlo!

luego permitir al servidor leer y escribir en nuestra aplicación, Apache corre como usuario www-data, una forma de permitirle leer los archivos y escribir (concretamente debe escribir en ./tmp/*), sería poner el proyecto con nombre de usuario www-data y luego añadirnos a nosotros como miembro de www-data, esta es una opción, puede haber cientas, dependiendo del sistema de cada uno…

$ chown www-data:www-data -R . # apache corre como usuario www-data
$ sudo vigr # modificamos la linea de www-data, si teníamos algo como esto:
www-data:x:33:
la modificamos a algo como esto:
www-data:x:33:blaxter

Ahora, ya para finalizar, solo nos queda modificar el .htaccess, concretamente ~/dev/rails/public/.htaccess, que debe quedar así:

Options +FollowSymLinks +ExecCGI
RewriteEngine On
#####################################
# Si configuramos la aplicacion con un Directory mas un alias tipo
# Alias /rails /home/blaxter/dev/rails/public
# Deberíamos descomentar la siguiente linea
# RewriteBase /rails
#####################################
RewriteRule ^$ index.html [QSA]
RewriteRule ^([^.]+)$ $1.html [QSA]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ dispatch.fcgi [QSA,L]

ErrorDocument 500 “Application error. Rails application failed to start properly”

Ok, todo hecho. Ya solo queda entrar a http://rails/ o http://rails/adminDeCosas o http://rails/prueba y todo funcionará!. Además podremos ver el log en ~/dev/rails/log/apache.log :). Suerte!

HowTo: Instalando unos buenos Railes [RoR]

rails.pngRuby es un lenguaje de script similar a python, que aunque no era muy conocido anteriormente (antes de RoR), gracias al framework RoR, está creciendo en popularidad a pasos agigantados y además por méritos propios.

El framework Rails se basa en el patrón de diseño MVC (model view controller). Igual otro día explico en detalle este patrón, pues es muy interesante. Ahora vayamos con la instalación de Rails, que es de lo que se trata en este post.

Podríamos hacer la instalación con un simple $ sudo aptitude install rails, pero es mejor instalarlo mediante Gem, un gestor de paquetes para ruby (algo así como PEAR para php o cpan.org para perl, o el propio apt-get para Debian)

Supongo que tenemos instalada una base de datos, por ejemplo MySQL, y repositorios universe de Ubuntu dapper (para otras distros se podrían aplicar todos los pasos, realizando, quizás, ciertas modificaciones…). Primero instalaremos Ruby y unos paquetes adicionales necesarios para el correcto funcionamiento de Gem

$ sudo aptitude install ruby irb rdoc libzlib-ruby libyaml-ruby liberb-ruby rdoc libdrb-ruby libyaml-ruby libzlib-ruby

irb es un entorno de ejecución interactivo de ruby, podemos ejecutarlo y hacer un hola mundo xD

$ irb
irb(main):001:0> print “hola mundo!”
hola mundo!=> nil

innncreible xD. Ahora instalemos Gem


$ cd /tmp && wget http://rubyforge.org/frs/download.php/28174/rubygems-0.9.5.tgz
$ tar xfz rubygems-0.8.11.tgz
$ cd rubygems-0.8.11/
$ sudo ruby setup.rb

Ok, ya lo tenemos instalado, para información de como funciona, ver aquí. Ahora para instalar rails solo tenemos que hacer:

$ sudo gem install rails --include-dependencies

Ya está!, tenemos Ruby On Rails instalado! Mooola. Vale, pero y ahora que hago?. Vamos a hacer un par de pruebas para ver que realmente funciona todo bien.

Suponemos que nuestro directorio de trabajo será ~/dev/rails, por ejemplo:

$ cd ~/dev
$ rails rails # el parametro es el nombre de la carpeta que creará
$ cd rails
$ script/server

Ok, ahora si entramos en http://localhost:3000/ veremos la pantalla de bienvenida de Rails. Vale, funcionar, funciona, o algo sale. Pero como pongo hago yo cosas?, eh?, eh?. Vamos a hacer un hola mundo!.

Paramos el servidor (ctrl+c) y ejecutamos

$ script/generate controller prueba
$ vim app/controllers/prueba_controller.rb # lo modificamos tal que asi:
$ more app/controllers/prueba_controller.rb
class PruebaController < ApplicationController def index render_text "hola mundo!" end def lalala render_text "como mola esto nano!" end end

$ script/server

Y al entrar a http://localhost:3000/prueba veremos nuestro gran hola mundo! :). Y entrando a http://localhost:3000/prueba/lalala veríamos el otro texto que hemos escrito. Inncreible xD.

Vale, ya hemos hecho una tontería, hagamos otra más cool. Al inicio de este coñazo HowTo dije que suponía que teníamos instalada MySQL (u otra BD). Instalemos soporte para ruby para nuestra base de datos

$ sudo aptitude install libmysql-ruby1.8 # o el equivalente para nuestra BD!
$ irb
irb(main):001:0> require "mysql"
=> true
irb(main):002:0> exit

Creamos un par de bases de datos y por temas de seguridad también sería aconsejable crear un usuario con permisos más restrictivo, usaré "root" por simplificar este howto

$ sudo mysql -u root -p
mysql> create DATABASE rails;
mysql> create DATABASE rails_test;
mysql> quit

Ahora vamos a decir a Rails cual es nuestra base de datos, editamos ~/dev/rails/config/database.yml quedando algo como esto:

$ more config/database.yml
development:
adapter: mysql
database: rails
username: root
password: NUESTRAPASS
host: localhost

test:
adapter: mysql
database: rails_test
username: root
password: NUESTRAPASS
host: localhost

production:
adapter: mysql
database: rails
username: root
password: NUESTRAPASS
host: localhost

Vale, todo perfecto. Ahora hagamos lo siguiente:

$ script/generate model Thing
$ vim db/migrate/001_create_things.rb
algo como esto (por ejemplo...):

class CreateThings < ActiveRecord::Migration def self.up create_table :things do |t| t.column :nombre, :string t.column :uso, :string t.column :cantidad, :integer end end def self.down drop_table :things end end

$ rake db:migrate
$ script/generate scaffold Thing AdminDeCosas
$ script/server

Ahora entrando a http://localhost:3000/AdminDeCosas podremos añadir entradas de "cosas", verlas, editarlas y borrarlas. Curioso, eh?

Para próximos posibles post me apunto integrarlo con apache y profundizar más en las posibilidades de Rails. Para cualquier duda, crítica, opinión, insulto o desvario mental, los comentarios ;).

Ruby on Rails

Bastante curioso oye, actualmente hay tres tecnologías clave en el desarrollo web (bueno cuatro, pero java es lo peor del mundo, así que lo ignoro) PHP, ASP.NET y RoR.

(Nota: el comando que ejecuto se podría resumir en que se pilla la cabecera http que nos devuelve el servidor)

PHP

[blaxter@helicon]:~$ wget -S –spider http://www.php.net
–15:27:55– http://www.php.net/
=> `index.html’
Resolviendo www.php.net… 64.246.30.37
Connecting to www.php.net|64.246.30.37|:80… conectado.
Petición HTTP enviada, esperando respuesta…
HTTP/1.1 200 OK
Date: Sat, 11 Feb 2006 14:06:42 GMT
Server: Apache/1.3.26 (Unix) mod_gzip/1.3.26.1a PHP/4.3.3-dev
X-Powered-By: PHP/4.3.3-dev
Last-Modified: Sat, 11 Feb 2006 14:13:35 GMT
Content-language: en
Connection: close
Content-Type: text/html;charset=ISO-8859-1
Longitud: no especificado [text/html]
200 OK

ASP.NET

[blaxter@helicon]:~$ wget -S –spider http://asp.net
–15:26:18– http://asp.net/
=> `index.html’
Resolviendo asp.net… 66.129.67.14
Connecting to asp.net|66.129.67.14|:80… conectado.
Petición HTTP enviada, esperando respuesta…
HTTP/1.1 302 Found
Connection: keep-alive
Date: Sat, 11 Feb 2006 14:26:24 GMT
Server: Microsoft-IIS/6.0
X-Powered-By: ASP.NET
X-AspNet-Version: 2.0.50727
Location: http://asp.net/Default.aspx?tabindex=0&tabid=1
Cache-Control: private
Content-Type: text/html; charset=utf-8
Content-Length: 43204
200 OK

RoR

[blaxter@helicon]:~$ wget -S –spider http://rubyonrails.org/
–15:25:18– http://rubyonrails.org/
=> `index.html’
Resolviendo rubyonrails.org… 70.84.143.109
Connecting to rubyonrails.org|70.84.143.109|:80… conectado.
Petición HTTP enviada, esperando respuesta…
HTTP/1.1 200 OK
Date: Sat, 11 Feb 2006 14:25:23 GMT
Server: Apache
X-Powered-By: PHP/5.0.3
Vary: Accept-Encoding
X-Powered-By: The blood, sweat and tears of the fine, fine TextDrive staff
Served-By: TextDrive’s Textpache
Keep-Alive: timeout=5, max=80
Connection: Keep-Alive
Content-Type: text/html; charset=UTF-8
Longitud: no especificado [text/html]
200 OK

Comentar que la página de RoR no tiene mucha parte dinámica, así que tiene excusa para no usar algo mas avanzado como es RoR, posiblemente la parte de php se centre exclusivamente en includes() y poco mas, si me apuras templates y/o logs varios.