Haml vs Slim

Slim es simplemente un mejor Haml en todos los aspectos.

Configuración de una aplicación Rails 4.2 tradicional

Actualmente existen dos enfoques para desarrollar una aplicación web, el tradicional, que es impulsado por frameworks como Rails y el de las JSON API + SPA.

En el enfoque tradicional tenemos todo nuestro código en una aplicación Rails. En ella toda la lógica de negocios está en los modelos, el cómo la operamos en los controladores y la interfaz de usuario en las vistas. Programamos las vistas con Slim, Ruby y Sass, usamos gemas como simple_form para crear fácilmente formularios en Ruby.

El enfoque JSON API + SPA, por otra parte, se cuenta con dos componentes: La aplicación servidor (API) y un cliente Javascript (o móvil) para la vista.

En principio, puede parecer atractiva la idea de hacer las vistas con Ruby y sus amigotes, pero la verdad es que no hay como trabajar en el ambiente natural del lenguaje donde se despliegan nuestras aplicaciones: usualmente Javascript.

En principio, también, puede parecer meh trabajar con HTML y amigos, sin embargo cuando descubres cosas como Grunt, Gulp, Yeoman, Bower, AngularJS y demás, —Y— lo que te permiten hacer en cuestión de organización de tu proceso de desarrollo, simplemente no puedes dar marcha atrás.

El desarrollo del cliente (UI) es en sí, un universo propio, y requiere de herramientas adecuadas para poderlo desarrollar de adecuadamente.

Ambos enfoques me agradan y he usado ambos en varios proyectos. Sin embargo, me siento más atraído hacia las JSON API + SPA debido a la clara separación entre front end y back end.

Preliminares

Commit inicial

Para generar el proyecto y hacer el primer commit:

rails new rails_app --database=postgresql
cd rails_app
git init
git add .
git commit -m "Commit inicial."

Configuración inicial

Agrega estas gemas a tu Gemfile:

group :development, :test do
  ...
  # Framework para pruebas
  gem 'minitest-rails'
  # Para generar objetos de prueba
  gem 'fabrication'
  # Para generar datos de prueba
  gem 'faker'
end
 
# Escribe las vistas en Slim en vez de HTML
gem 'slim-rails'
# Crea formularios de manera concisa
gem 'simple_form'

Después en la terminal:

bundle
rails g minitest:install
rails g simple_form:install

Modifica config/application.rb:

config.time_zone = 'Mexico City'
config.i18n.default_locale = 'es-MX'
 
config.generators do |g|
  g.test_framework :minitest, :spec => true, :fixture => false
end

Crea un usuario y una base de datos para esta aplicación, revisa ls guía: Cómo instalar PostgreSQL en Ubuntu

Configura el host, username y password en config/database.yml:

default: &default
  adapter: postgresql
  encoding: unicode
  host: localhost
  user: usuario_ejemplo
  password: xxx

Ejecuta en la terminal:

rake db:create

Descarga el archivo es-MX.yml y ponlo en: config/locales/es-MX.yml
Lista de localizaciones para Rails

Modifica config/initializers/inflections.rb:

ActiveSupport::Inflector.inflections(:en) do |inflect|
  inflect.clear
 
  inflect.plural(/$/, 's')
  inflect.plural(/([^aeéiou])$/i, '\1es')
  inflect.plural(/([aeiou]s)$/i, '\1')
  inflect.plural(/z$/i, 'ces')
  inflect.plural(/á([sn])$/i, 'a\1es')
  inflect.plural(/é([sn])$/i, 'e\1es')
  inflect.plural(/í([sn])$/i, 'i\1es')
  inflect.plural(/ó([sn])$/i, 'o\1es')
  inflect.plural(/ú([sn])$/i, 'u\1es')
 
  inflect.singular(/s$/, '')
  inflect.singular(/es$/, '')
 
  inflect.irregular('el', 'los')
end

Realiza el commit con los cambios en la configuración.

git add .
git ci -m "Configuración inicial."

¡Listo, a desarrollar! 😀

Recursos

Inflexiones en español para Rails
Configurar usuario y base de datos en PostgreSQL

Cómo instalar Ruby 2.2 con rbenv en Ubuntu 14.10

Después de haber pasado de instalar Ruby a mano, a instalarlo usando el cómodo RVM, me he ido ahora por rbenv. Otra opción, aun más ligera es chruby por si quieren echarle un ojo.

Preliminares

Vas a necesitar git, instálalo siguiendo esta guía.

Instalación de rbenv

¿Instalación local o en un VPS?

Si vas a instalar Ruby para desplegar aplicaciones en un VPS (Virtual Private Server, tipo Linode), es recomendable crear un usuario específico para ello.

Si deseas una instalación local, sáltate este paso y pasa a clonar el repositorio directamente en tu $HOME

sudo adduser deployer
sudo usermod -a -G sudo deployer
sudo su deployer
cd ~

Clona el repositorio

git clone git://github.com/sstephenson/rbenv.git ~/.rbenv

Agrega ~/.rbenv/bin al $PATH para tener acceso al comando rbenv.

echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc

Agrega rbenv init a tu shell para habilitar los shims y la función de autocompletar.

echo 'eval "$(rbenv init -)"' >> ~/.bashrc

Reinicia tu shell para que los cambios surtan efecto.

exec $SHELL

Plugins para rbenv

ruby-build es un plugin que te permite instalar las diferentes versiones de Ruby de una manera sencilla y accesible.

El proyecto ruby-build te permite usar el comando rbenv install para agregar nuevas versiones de Ruby.

git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build

Y para no volver a escribir rbenv rehash nunca más después de instalar una gema:

git clone https://github.com/sstephenson/rbenv-gem-rehash.git ~/.rbenv/plugins/rbenv-gem-rehash

Instalación de Ruby

Instala los prerequisitos (obtenidos de los que lista RVM como requisitos para Ubuntu):

sudo apt-get install bison libreadline-dev libyaml-dev libsqlite3-dev sqlite3 libxml2-dev libxslt-dev autoconf texinfo libncurses-dev automake libssl-dev build-essential libffi-dev

Para ver la lista de versiones disponibles, teclea en una terminal:

rbenv install --list

Cuando salgan nuevas versiones de Ruby, para poder instalarlas, teclea en una terminal:

cd ~/.rbenv
git pull
cd ~/.rbenv/plugins/ruby-build
git pull

Ahora, para instalar Ruby versión 2.2.2, y ponerlo como la versión por defecto, teclea en la terminal:

rbenv install 2.2.2
rbenv global 2.2.2

Con Ruby instalado y configurado, al escribir esto:

ruby -v

Debe aparecer algo como:

ruby 2.2.2p95 (2015-04-13 revision 50295) [x86_64-linux]

Verifica si hay actualizaciones para el administrador de paquetes gem:

gem update --system

También verifica si hay actualizaciones para las gemas que vienen instaladas por defecto:

gem update

¡Listo, ya puedes ejecutar código Ruby en tu máquina!

Acelera la instalación de gemas (opcional)

Para instalar más rápidamente las gemas, puedes desactivar la instalación de su documentación con:

echo 'gem: --no-document' >> ~/.gemrc

Instalación de Rails y Compass

Para instalar la versión estable más reciente de Rails y Compass, ejecuta:

gem install rails compass

Teclea:

rails --version

Debe aparecer algo como:

Rails 4.2.1

Recursos

Setup Ruby On Rails on Ubuntu 14.04 Trusty Tahr

Cómo instalar PostgreSQL 9.4 en Ubuntu 14.10

Abre una terminal y teclea:

sudo apt-get install postgresql postgresql-client postgresql-contrib libpq-dev

Esto instala el cliente y servidor de la base de datos y algunos scripts de utilería. El paquete de libpq-dev nos servirá para poder compilar la gema Ruby para PostgreSQL más adelante.

Confirma que la instalación terminó adecuadamente tecleando:

psql --version

En mi caso la respuesta fue:

psql (PostgreSQL) 9.4.1

PostgreSQL Ruby gem

Si planeas usar PostgreSQL con Ruby, necesitarás esto:

gem install pg

En Rails, puedes crear una aplicación configurada para usar PostgreSQL así:

rails new mi-nueva-aplicacion -d postgresql

Cómo crear un usuario en la base de datos para la aplicación Rails

Para crear un usuario llamado usuario_ejemplo que puedas usar en tu database.yml, teclea:

sudo su postgres -c psql
CREATE USER usuario_ejemplo WITH PASSWORD 'xxx';
ALTER ROLE usuario_ejemplo WITH CREATEDB;
\q

Luego en tu database.yml configura el ambiente development, hay otros dos que también debes configurar: test y production:

development:
  adapter: postgresql
  encoding: unicode
  database: usuario_ejemplo
  pool: 5
  username: usuario_ejemplo
  password: xxx
  host: localhost

Asigna el host en database.yml

Es posible que al ejecutar algún comandos de base de datos (rake db:create, rake db:migrate), te encuentres con un error que dice algo como:

FATAL: Peer authentication failed for user “X”

Para evitarlo necesitas editar el archivo config/database.yml de tu aplicación y agregar la siguiente línea en las tres configuraciones (development, test y production):

host: localhost

¡Listo! 😀

Tuneando PostgreSQL

Es importante tunear el servidor PostgreSQL para tener un buen rendimiento cuando despliegues en un ambiente de producción.
Checa esta excelente guía: PostgreSQL: HW Tunning

Recursos

PostgreSQL add or create a user account and grant permission for database
Install PostgreSQL on Ubuntu 8.04 (cómo acceder a tu DB desde otras máquinas en la red).
Switching Rails to PostgreSQL
PostgreSQL — Guía Ubuntu Wiki
Is there a way to break into a PostgreSQL database if you forgot the password?
Improving the Command-Line Postgres Experience

Un par de problemas con Passenger fáciles de resolver

Si al instalar Passenger con:

  1. gem install passenger

Te sale el siguiente mensaje:

  1. ...
  2. ** Execute (dry run) nginx
  3. /home/tlacaelel/.rvm/gems/ruby-1.9.2-p180/gems/passenger-3.0.7/lib/phusion_passenger/standalone/runtime_installer.rb:224:in `*': negative argument (ArgumentError)
  4. ...

Se resuelve al reintentar la instalación, teclea de nuevo:

  1. gem install passenger

Si después al ejecutarlo con:

  1. passenger start -p3001

Te aparece:

  1. You can stop Phusion Passenger Standalone by pressing Ctrl-C.
  2. ===============================================================================
  3. Cannot execute '/var/lib/passenger-standalone/3.0.7-x86-ruby1.9.2-linux-gcc4.5.2-1002/support/helper-scripts/prespawn http://0.0.0.0:3001': Permission denied (13)

Lo resuelves con:

  1. sudo chmod +x /var/lib/passenger-standalone/3.0.7-x86-ruby1.9.2-linux-gcc4.5.2-1002/support/helper-scripts/prespawn

undefined method `version’ for nil:NilClass — Cómo actualizar rubygems 1.5.0 a 1.5.2

Si tienes instalado rubygems 1.5.0 o 1.5.1 y tratas de actualizarlo con el comando de siempre, te encontrarás con esto:

  1. $ gem update --system
  2. Updating RubyGems
  3. ERROR:  While executing gem ... (NoMethodError)
  4.     undefined method `version' for nil:NilClass

Para arreglarlo es necesario instalar la gema rubygems-update.
Teclea lo siguiente en tu terminal:

  1. gem install rubygems-update
  2. update_rubygems

Y verás algo como esto:

  1. $ update_rubygems
  2. RubyGems 1.5.2 installed
  3.  
  4. === 1.5.2 / 2011-02-10
  5.  
  6. NOTE:  RubyGems 1.5.0 and 1.5.1 have a broken <tt>gem update --system</tt>.
  7.  
  8. To upgrade you'll need to use the manual upgrade recipe.  Using sudo/su as
  9. appropriate:
  10.  
  11.   $ gem install rubygems-update
  12.   $ update_rubygems
  13.  
  14. Bug Fixes:
  15.  
  16. * Fixed <tt>gem update --system</tt>.
  17.   RubyGems can now update itself again.

Ahora ya puedes actualizar de nuevo tu rubygems con:

  1. gem update --system

ERROR: While executing gem … (ArgumentError) undefined class/module YAML::PrivateType

Si al tratar de instalar una gema te sale el error mostrado a continuación, seguramente es porque el autor hizo un lanzamiento con rubygems 1.5.0.

  1. $ rake install
  2. (in /home/oewolf/development/gamedev/github/missile-command-ruby)
  3.   Successfully built RubyGem
  4.   Name: missile-command-ruby
  5.   Version: 0.0.6
  6.   File: missile-command-ruby-0.0.6.gem
  7. Executing "ruby -S gem install ./pkg/missile-command-ruby-0.0.6.gem":
  8. ruby -S gem install ./pkg/missile-command-ruby-0.0.6.gem
  9. ERROR:  While executing gem ... (ArgumentError)
  10.     undefined class/module YAML::PrivateType
  11. rake aborted!
  12. Command failed with status (1): [ruby -S gem install ./pkg/missile-command-...]

Entonces, lo indicado aquí es hacer un relanzamiento de la gema, una vez que hayamos actualizado a rubygems 1.5.2 o superior.

Depredado en

undefined method ‘version’ for nil:nilclass ??? hmmm…

Missing host to link to! Please provide :host parameter or set default_url_options[:host]

Al estar desarrollando una aplicación web con Rails 3 y Devise, me apareció el siguiente error al estar jugando con la característica lockable:

ActionView::Template::Error (Missing host to link to! Please provide :host parameter or set default_url_options[:host])

Investigando un poco me topé con que la solución consistía en hacer caso a la indicación que aparece en el README de Devise. Je.

Necesitamos configurar en cada ambiente (development, production, etc.) las URLs que se emplearán en el envío de correos electrónicos:

Aquí está la configuración para config/environments/development.rb:

config.action_mailer.default_url_options = { :host => 'localhost:3000' }

Y aquí una de ejemplo para config/environments/production.rb:

config.action_mailer.default_url_options = { :host => 'lobotuerto.com' }

Problemas con rake con Ruby 1.8 y Ruby 1.9 instalados

Hace un par de meses que no tengo salida de video en mi laptop, pero he podido laborar con ella por medio de un ssh -X.

Sin embargo, pienso mandarla a reparar pronto, así que decidí mudar mis proyectos de trabajo a una máquina de escritorio que tengo por ahí.

En la de escritorio usaba primariamente Ruby 1.9. y no había tocado la instalación de Ruby 1.8 desde hacía ya un buen rato.

Debo agregar que todos los proyectos del trabajo que usan Rails, lo hacen sobre Ruby 1.8. Así que me puse a instalarle todas las gemas que hacían falta, entre ellas: Rails.

Cuando terminé, accedí a uno de mis proyectos y quise ver el listado de las tareas con un simple:

rake -T

Sólo para ser presentado con un críptico:

rake aborted!
no such file to load -- cucumber/rake/task

WTF? pensé, ¿qué tiene que ver el cucumber con un rake -T?
Así que instalé el cucumber en el ambiente de Ruby 1.8 para ver si eso solucionaba el problema, y no, seguía igual.

Entonces escribí:

rake -T --trace

Y cuál sería mi sorpresa al ver:

rake aborted!
no such file to load -- cucumber/rake/task
/usr/local/lib/ruby19/gems/1.9.1/gems/activesupport-2.3.5/lib/active_support/dependencies.rb:156:in `require'

!!!
¿Por qué esta utilizando las gemas del 1.9 si tengo activado el 1.8?

Después de darme de topes un rato ubiqué el problema …

El archivo rake que se encuentra alojado en /usr/local/bin/rake indica de manera explícita que debe ejecutarse con Ruby 1.9:

#!/usr/local/bin/ruby19

Lo que hay que hacer es editarlo con:

sudo gedit /usr/local/bin/rake

Y cambiar esa línea por esta otra:

#!/usr/bin/ruby

Listo, ahora rake empleará la versión de Ruby que tengamos activada en nuestro sistema. :)

Una mejor manera de instalar Ruby en Ubuntu es con rbenv: Cómo instalar Ruby con rbenv en Ubuntu.

lotu — Un framework para desarrollo de juegos en Ruby

[singlepic=484,60,,,left]Pues aquí estoy con un nuevo proyecto. :)

Un framework para desarrollar juegos en Ruby.

Los antecedentes

Después de terminar mi clon de Tetris llamado rubytris, decidí darme a la tarea de implementar otro clon de los juegos de antaño —¡y uno de mis favoritos!: Missile Command.

Debo comentar que a medio camino se me ocurrió utilizar comportamientos de direccíón (steering behaviors) para modelar el movimiento de los misiles —y algunos otras entidades— para una experiencia más envolvente.

Así, le puse pausa al Missile Command y comencé a desarrollar otro proyecto llamado ruby_steering_behaviors que cuenta ya con los comportamientos necesarios para utilizarlo en mi juego nuevo).

Durante la implementación de esos dos proyectos comencé a desarrollar abstracciones y clases útiles que no tenía en rubytris (mi primer juego):

  • Estados de juego
    Auxiliado por una máquina de estados es mucho más sencillo implementar las diversas pantallas de juego, entradas (splash screens) y menús.
  • Manejador de recursos
    Para un fácil acceso a las imágenes, fuentes y sonidos.
  • Manejador de eventos
    Un sistema de disparo y captación de eventos.
  • Funciones auxiliares
    Para facilitar el despliegue de texto, imágenes, sonidos.
  • Clases útiles
    Un contador de cuadros por segundo (FPS counter).
    Un visor (viewport) para poder tener espacios virtuales de tamaños arbitrarios, con acercamientos, alejamientos y control de entrada.

Desgraciadamente el trabajo y otras actividades de mi vida cotidiana me absorbieron demasiado y dejé ambos proyectos abandonados por un rato.

Pero, ahora que logré hacerme de un tiempecito decidí retomarlos y me pregunté:
¿por qué no desarrollar un framework que incluya todo eso (más lo que salga)? ¿podría ser provechoso para alguien más? Creo que sí.

Y así nació lotu.

lotu

lotu es un framework naciente que está basado en gosu, una biblioteca para creación de juegos en 2D.

Siendo gosu una biblioteca, te provee únicamente con las funciones básicas para crear un juego y nada más.

lotu, por otro lado se encargará de hacer el proceso de creación de juegos simple e intuitivo. gosu provee las herramientas y lotu los medios. gosu da el con qué y lotu provee el cómo.

Sin un marco de trabajo (framework), eres totalmente libre de organizar tu código de la forma que más te plazca, pero corres el riesgo de caer en el caos completo.

Un framework impone ciertas convenciones, te enseña un estilo de trabajo. Si las convenciones ayudan a desarrollar de una manera más rápida y menos compleja tu proyecto, entonces podemos decir que el framework es exitoso.

Como experimento he decidido desarrollar a la par mi juego nuevo y lotu. Espero que de esta manera ambos se retroalimenten y así obtener un mejor resultado.

lotu gem

Nunca antes había hecho una gema en Ruby. Se me hacía un proceso esotérico y extraño (lotu es mi primera gema ¡que emoción!). 😀

Pero jeweler realmente te la pone fácil, demasiado diría yo jeje. Si no me crees, checa este video:
Gemcutter & Jeweler

La gema la puedes instalar con:

  1. sudo gem install lotu

Sin embargo si quieres ir al día con el desarrollo te aconsejo que lo cheques en github.

Otros frameworks

¿Por qué no usar un framework existente como chingu?

La razón principal es aprendizaje. 😉

¡Es hora de programar! 😀

Cómo mostrar las sentencias SQL en la consola de Rails

Al operar la consola de Rails, muchas veces quisieramos que al usar nuestros modelos se nos mostrara el SQL que se está generando.

Sólo agrega las siguientes líneas a tu archivo ~/.irbrc

  1. if ENV['RAILS_ENV']
  2.   # Called after the irb session is initialized and Rails has been loaded
  3.   IRB.conf[:IRB_RC] = Proc.new do
  4.     logger = Logger.new(STDOUT)
  5.     ActiveRecord::Base.logger = logger
  6.     ActiveResource::Base.logger = logger
  7.   end
  8. end

Ahora, cuando interactúes con la base de datos verás algo como esto:

  1. >> Oficina.find 1
  2.   Oficina Load (1.2ms)   SELECT * FROM "oficinas" WHERE ("oficinas"."id" = 1) 
  3. => #<Oficina id: 1, nombre: "CAMPECHE BCMR", organizacion_id: 2, activa: true>

Referencia

Showing SQL statements in the Rails console