Apuntes de Rails

y de otras cosas

Borrar sesiones viejas en Rails 2.3 con ActiveRecordStore

Tarea rake para borrar las sesiones que no se han utilizado en las ultimas 3 horas.

desc "Borrar de la base de datos la sesiones que han expirado ."
task :delete_old_sessions => :environment do
 sesiones = ActiveRecord::SessionStore::Session.find(:all, :conditions => ['updated_at < ?', 3.hours.ago])
 sesiones.each {|s| s.delete}
end

Instalación de Rails y Passenger en Ubuntu 8.04 (Hardy)

Instalación de ruby:

sudo apt-get install build-essential 
sudo apt-get install ruby rdoc ri irb libopenssl-ruby1.8 ruby1.8-dev

Instalación de rubygems desde las fuentes, porque los paquetes para Ubuntu no están disponibles para la última versión:

cd /usr/local/src/
sudo wget http://rubyforge.org/frs/download.php/45905/rubygems-1.3.1.tgz
sudo tar xzfv rubygems-1.3.1.tgz
cd rubygems-1.3.1
sudo ruby setup.rb

sudo ln -s /usr/bin/gem1.8 /usr/bin/gem

Ahora puedes borrar los ficheros que has descargado en/usr/local/src/ si quieres.

Instalación de sqlite3 (opción por defecto a partir de rails 2 para la base de datos):

sudo apt-get install sqlite3 libsqlite3-dev
sudo gem install sqlite3-ruby

Instalación de Rails:

sudo gem install rails

Instalación de apache y mysql:

sudo apt-get install apache2 
sudo apt-get install mysql-server mysql-client libmysqlclient15-dev

sudo gem install mysql

Para usar virtual hosts en apache quitar la linea

NameVirtualHost * 

de /etc/apache2/sites-available/default

Cambiar la primera linea por <VirtualHost *:80>

En /etc/apache2/apache2.conf poner

NameVirtualHost *:80

<IfModule mod_ssl.c>
    NameVirtualHost *:443
</IfModule>

antes de

# Include of directories ignores editors' and dpkg's backup files,
# see README.Debian for details.

# Include generic snippets of statements
Include /etc/apache2/conf.d/

# Include the virtual host configurations:
Include /etc/apache2/sites-enabled/

Crear /var/www/default y mover ahí­ el index.html que hay en /var/www

Cambiar el DocumentRoot de /etc/apache2/sites-available/default al nuevo directorio.

Instalación de Passenger (a.k.a mod_rails):

sudo gem install passenger
sudo passenger-install-apache2-module

Y seguir las instrucciones. No te olvides de poner las tres lí­neas que te dice Passenger en el fichero de configuración de apache /etc/apache2/apache2.conf (yo lo pongo antes de lo del VirtualHost del párrafo anterior).

Otra opción de instalación para Ubuntu Hardy 8.04 es el paquete que ha hecho BrightBox.

Luego en el virtual host para la aplicación Rails pones como DocumentRoot la ruta al directorio public de la aplicación y ya está. Si quieres afinar más la configuración mí­rate la guí­a de usuario de Passenger.

Actualizar RubyGems a la versión 1.3.1

La versión 1.1 y la 1.2 de RubyGems tienen problemas para actualizarse, si después de ejecutar

$ sudo gem update --system 

ves un “Nothing to update”, prueba a instalar y ejecutar la gema rubygems-update:

$ sudo gem install rubygems-update
$ sudo update_rubygems

Y a correr :)

Cierre del plazo de inscripción para la Conferencia Rails 2008

Como la mayorí­a ya sabréis, la Conferencia Rails 2008 será los próximos dí­as 13 y 14 de noviembre en Madrid, en la Escuela de Teleco.

Para cerrar temas de catering, sobre todo para la cena del jueves, desde el equipo de organización necesitamos cerrar las inscripciones y los pagos el próximo dí­a 5 de noviembre (el dí­a 5 tendrí­a que estar ya el pago en nuestra cuenta), para que de tiempo a organizarlo todo.

Así­ que si vas a venir y todaví­a no te has apuntado, ¿a qué esperas? Ya sabemos que estas cosas se suelen dejar para el final, pero necesitamos tener cerrado el número de asistentes cuanto antes.

Si lo que pasa es que no lo tienes claro puedes mirar el calendario de charlas y terminar de convencerte de que no te lo puedes perder ;)

Migrar los repositorios svn a otro servidor

Ya sé que lo que más mola ahora es Git, pero de momento en Dabne seguimos manteniendo nuestros repositorios de código en Subversion, mientras vamos trasteando con Git y valorando si cambiar del todo o seguir con un hí­brido de svn + git.

El caso es que esta semana he tenido que mover los repos a un nuevo servidor y así­ es cómo lo he hecho.

En el servidor donde están los repos hay que hacer un ‘dump’ de cada uno de ellos, copiarlos al servidor 2, y cargarlos en un repo nuevo recién creadito.

Serí­a así­:

serv1$ svnadmin dump nombre_repo > nombre_repo.dump

Se copian los ficheros .dump al servidor 2 y se hace:

serv2$ svnadmin create nombre_repo
serv2$ svnadmin load nombre_repo < nombre_repo.dump

Como tení­a varios he probado a hacerlo con un scriptcillo en ruby directamente desde la lí­nea de comandos:

serv1$ ruby -e "Dir.foreach('.'){|x| system \"svnadmin dump #{x} > #{x}.dump\"}"

serv2$ ruby -e "Dir.glob('*.dump'){|x| system \"svnadmin create #{x.split('.')[0]} \"}"
serv2$ ruby -e "Dir.glob('*.dump'){|x| system \"svnadmin load #{x.split('.')[0]} < #{x} \"}"

Si la url del repositorio cambia luego en cada copia de trabajo hay que ejecutar:

$ svn switch --relocate url_antigua url_nueva

Cuidado con lo que va delante de relocate que son dos -, no uno de esos largos.

Esta vez he configurado el acceso a los repositorios con apache2 por https, pero eso queda para otro post.

Autenticación de usuarios con restful_authentication

Pasos para crear una aplicación rails con autenticación de usuarios.

Crear la aplicación rails:

$ rails myapp
$ cd myapp

Instalar el plugin restful_authentication:

$  script/plugin install http://svn.techno-weenie.net/projects/plugins/restful_authentication/

Generar el sistema de autenticación:

$ script/generate authenticated user session
$ rake db:migrate

En config/routes.rb añadir lo siguiente antes de las rutas por defecto (las dos últimas)

map.resources :users
map.resource  :session, :controller => 'session'

map.signup '/signup', :controller => 'users', :action => 'new'
map.login  '/login', :controller => 'session', :action => 'new'
map.logout '/logout', :controller => 'session', :action => 'destroy'

En app/controllers/application_controller.rb poner la lí­nea siguiente, que viene en los controladores user_controller.rb y session_controller.rb que ha creado el plugin.

include AuthenticatedSystem

Poniendolo en application_controller.rb hacemos que la autenticación esté disponible para todos los controladores.

Ahora en los controladores para los que queramos restringir el acceso a usuarios autenticados tendremos que poner un filtro:

before_filter :login_required

A este filtro le podemos poner parámetros para indicarle que sólo se aplique a algunas acciones o que se aplique a todas excepto a algunas, por ejemplo:

before_filter :login_required, :only => [:create, :destroy]
before_filter :login_required, :except => [:index, :show]

En mi caso últimamente es habitual que necesite controlar el acceso a toda la aplicación salvo a unas pocas acciones por lo que pongo el before_filter en application_controller.rb y luego pongo un skip_before_filter donde sea necesario, que en este caso es en users_controller.rb y session_controller.rb para permitir crear nuevos usuarios y hacer login, que en realidad es crear una nueva session. Por tanto en estos dos controladores pongo:

skip_before_filter :login_required, :only => [:new, :create]

Si además hay una portada de la aplicación pública también habrá que aplicarle esto.

Para hacer que el registro sea con activación de usuarios por email, ver este otro post.

Mostrando el contenido del flash en Rails de forma compacta

No me acuerdo de dónde lo copié la primera vez, pero desde entonces ha ido pasando siempre de un proyecto a otro, porque es la forma que más me gusta de hacerlo.

En app/views/layouts/application.html.erb:

<% flash.each do |key, msg| -%>
  <%= content_tag :div, msg, :class => key, :id => 'flash' %>
<% end -%>

Esto crea un div con id flash y class la clave del hash, que normalmente será error o notice.

Luego en la css pones los estilos correspondientes y ya queda mucho mejor.


   #flash {
    padding: 0.5em;
    font-weight: bold;
   }
   .notice {
     background-color: #fff;
     color: #333;
     border: 1px solid green; 
   }
   .error {
     background-color: #ff6666;
     color: #333;
     border: 1px solid red; 
   }