Tag: rails (5 posts)
Lanzando Metroroto, un sistema colaborativo para traquear incidencias en el metro de madrid
Publicado el 09 Jun 2010

Hoy, después de un mes de desarrollo a ratos libres en @larubyrrom, hemos lanzado por fin Metroroto. Metroroto es un sistema colaborativo para intentar traquear las incidencias y averías del metro de madrid al instante. Es colaborativo porque las incidencias son reportadas por los propios usuarios a través de diferentes canales, como twitter o desde la propia web. Próximamente también lanzaremos una aplicación para android, para poder seguir las incidencias al minuto ( y también reportarlas ;) )
El funcionamiento es bastante sencillo, cuando un usuario sufre una incidencia en el metro, puede reportarla directamente en el formulario de nuestra web, o twitteando haciendo uso de los hashtags #metroroto #numerodelinea #nombredeestación.
Ejemplos:
#metroroto #l3 #legazpi Tren ardiendo en el anden
Tren detenido por 20 min #metroroto #l6 #carpetana
#metroroto #L3 #sol Tren averiado durante 10 minutos
Trucos::
Los hashtags pueden ir al principio o al final del twitt, pero siempre en el orden #metroroto #linea #estacion
Si por la estación donde ha ocurrido la avería, solo pasa una sola línea, no es necesario incluir el hashtag de la línea (#l6)
#metroroto #alvarado Metro parado por un rato largo
El hashtag de la linea, debe ir siempre precedido de una ele mayúscula o minúscula (#L2 o #l2).
Para que no se nos escape ninguna incidencia, intenta evitar poner espacios en el hashtag de la estación, sustitúyelos por guiones medios (-) o directamente, ponlo todo junto
Ejemplos
#metroroto #avenida-de-america Metro parado por un rato largo
#metroroto #avenidadeamerica Metro parado por un rato largo
Poco a poco iremos entrenando nuestro sistema de parseo de twitts, para que no se nos escape ninguno (incluso si no usas los hashtags de la linea y la estación :) ), pero hay que tener paciencia, y al menos siempre usar el hashtag #metroroto
Para enterarte de las incidencias tienes varias opciones: verlas directamente en nuestra web, seguir a nuestro usuario de twitter, @metroroto, leer nuestro feed o suscribirte por email en nuestra web, dónde podrás elegir si quieres recibir notificaciones de todas las lineas o sólo de las que coges a diario.
También puedes utilizar tu cliente de twitter favorito para suscribirte a ciertas búsquedas para limitar el número de incidencias que recibes, puedes probar a suscribirte a "#metroroto #l2" si sólo estas interesado en las averías de la linea 2 del metro.
Mostrar flashes en rails con jquery
Publicado el 20 Mar 2010
En entornos con una política de cache fuerte, puede ser un problema mostrar los típicos mensajes de flash para dar feedback al usuario después de haber realizado algún tipo de acción. Digo que puede ser un problema, porque puede ocurrir que nuestro sistema de cache (de página, fragmentos, etc) guarde la versión con el mensaje de flash y todos los usuarios verán esa versión.
Hay muchas maneras de evitar éste comportamiento, pero la última que he usado, es mostrar el mensaje de flash por javascript, una vez que la pagina ha cargado, con lo que nuestro sistema de cache nunca guardara la versión con el mensaje de flash.
Para hacerlo, primero debemos establecer una cookie en nuestro controlador, con el mensaje de flash en cuestión, en vez de asignarselo directamente al famoso flash[:notice] o flash[:error].
success.html do
cookies.delete 'flash_notice' if !cookies['flash_notice'].blank?
cookies['flash_notice'] = { :value => "Hemos recibido tu mensaje :) "}
redirect_to "new"
end
Con esto, primero vacíamos la cookie en cuestión, por si acaso tiene algún contenido y después guardamos nuestro mensaje en ella.
Luego solo nos queda mostrar nuestro mensaje de flash por javascript:
var myapp = {
load_flashes: function(notice_cookie,error_cookie){
notice = (($.cookie(notice_cookie) || '').replace(/\+/g, ' '));
error = (($.cookie(error_cookie) || '').replace(/\+/g, ' '));
if(notice != '') {
type = 'noticeExplanation';
content = notice;
$.cookie(notice_cookie, null);
}else if (error != ''){
type = 'errorExplanation';
content = error;
$.cookie(error_cookie, null);
}else{
type= '';
};
if (type != ''){
$("#flmessages").addClass("flashmsg");
$("#flmessages").addClass(type);
$("#flmessages").html(content);
};
return false;
},
}
Suponiendo que nuestro mensaje de flash lo vamos a mostrar en un div con id flmessages, lo que hacemos es dependiendo de que tipo de mensaje flash tengamos que mostrar, le añadimos la clase noticeExplanation o errorExplanation y el contenido de nuestra cookie a ese contenedor (ademas de la clase genérica flashmsg). Ademas también vaciamos la cookie que hemos leído para mostrar el mensaje.
Sólo nos quedaría cargar éste javascript en el document.ready de nuestra aplicación:
$(document).ready(function() {
myapp.load_flashes('flash_notice','flash_error');
});
Envío de emails con archivos adjuntos en Rails con ActionMailer
Publicado el 09 Mar 2010
Sólo a modo de recordatorio y para que quede constancia en algun lado para el futuro, voy a explicar la manera super simple que he usado para hacer el típico formulario de contacto (en mi caso para ofertas de trabajo) en el que se pueden adjuntar varios archivos (imágenes, pdf's, etc) y no queremos tener un modelo que gestione este tipo de recursos, ya sea porque no tiene la suficiente importancia en nuestra aplicación o porque preferimos recibir solo toda esa informacion por email.
Para gestionar los attachments con actionmailer, es tan simple como usar el método 'attachment' incluido en la api de rails, dentro de nuestro método en la clase 'ActionMailer::Base':
La manera en lo que yo lo he usado ha sido la siguiente:
attachs.each do |file|
attachment "application/octet-stream" do |attachment|
attachment.body = file.read
attachment.filename = file.original_filename
end unless file.blank?
end
dónde simplemente recibimos un array, 'attachs', que contiene los ficheros temporales recibidos en nuestro controller, e iteramos sobre ellos, llamando al método 'attachment', pasandole el content_type de 'application/octet-stream' (aqui podemos pasarle el content_type exacto si lo sabemos, pero como en mi caso dejo subir cualquier cosa, pongo este que es el más genérico) y un bloque donde leemos con un 'read' el archivo temporal recibido y le asignamos el nombre de fichero original.
Tan simple como eso, así la próxima vez que lo tenga que usar se dónde buscarlo facilmente ;)
En busca de la feature perdida en Authlogic
Publicado el 26 Feb 2010
El otro día me tope con algo, cuanto menos curioso. Acababa de poner una aplicación todavía en desarrollo en staging, es decir, había colgado una versión preliminar bajo usuario y clave. Ésta autenticación, un basic http, la había puesto en el servidor web por comodidad, en mi caso apache.
Mi aplicación a su vez cuenta con un back de administración, dónde uso authlogic para la autenticación, y para evitar problemas a la persona que iba a verificar el correcto funcionamiento de todo el site, decidí crear el usuario admin de mi aplicación en base de datos, con los mismo datos de acceso que los usados por la autenticación http del apache.
Cual fué mi sorpresa, cuando una vez deployada mi aplicación, accedí a mi url provisional, puse el usuario y contraseña en la autenticacion que me pedia mi navegador, la del apache, y vi que estaba logado en la aplicación como administrador. Pensé, upss, que extraño, e intenté cerrar sesión. Y digo intente, porque aunque daba a cerrar sesión, yo seguia siempre logado como administrador, y aparentemente la aplicación me estaba borrando mi sesión bien: en los logs la peticion al destroy de mi user_session se procesaba sin problemas, y me sacaba el típico mensaje de flash como que habia sido deslogueado de la aplicación, pero no era asi, yo seguia logado.
Y efectivamente, éste es el momento en el que todos decimos: ¡Cachis!, mi primer bug, no se donde está, pero seguro que es un bug.
Pero no era así, no había ningún bug ni en mi aplicación, ni en authlogic ni mucho menos. Era tan simple como que authlogic, por defecto, da soporte para autenticación http. Por lo tanto, estaba ocurriendo lo siguiente: yo, al meter las credenciales en mi navegador para la autenticación http, estaba mandando en cada petición que se hacía las credenciales, que por casualidad eran las mismas que las de el usuario administardor de base de datos. Authlogic, el muy listo de él, en Authlogic::Session::Base carga los siguientes modulos en éste orden:
include Params
include Cookies
include Session
include HttpAuth
Entonces, por orden, authlogic lo primero que hace es intertar autenticar al usuario por Params, es decir, intenta autenticar al usuario através de una url única generada para ese fin. Si ese no es el caso, entonces intenta autenticarlo por cookies, sino lo intenta por sesión, y por ultimo lo intenta por autenticación http.
En mi caso, yo estaba simplemente accediendo a la home, por lo que no estaba accediendo con una url única de inicio de sesión, ni tenia cookies para autenticar la usuario, ni estaba intentado crear una sesión para el. Simplemente, mi señor navegador, en cada request estaba mandando las credenciales de la autenticacion al apache, que se propagan evidentemente hasta mi app, y el authlogic las ve, e intenta buscar el usuario recibido y autenticarlo con la clave recibida. Como he dicho, yo tenia mi usuario en base de datos, que era administrador, con las mismas credenciales, y acababa siempre logado como tal :). Una buena feature de authlogic.
Se me ocurren varias utilidades de ésta feature, pero la mas evidente y rapida, es la posibilidad de autenticar a los usuarios de nuestra aplicacion sin necesidad de tener un controlador asociado a ello. Solo con tener nuestro modelo 'User' y 'UserSession':
class User < ActiveRecord::Base
acts_as_authentic
end
class UserSession < Authlogic::Session::Base
end
y en nuestro application_controller :
def current_user_session
return @current_user_session if defined?(@current_user_session)
@current_user_session = UserSession.find
end
def current_user
return @current_user if defined?(@current_user)
@current_user = current_user_session && current_user_session.user
end
podemos automaticamente poner una autenticacion http en nuestro servidor web, y authlogic se encargara de recibir esas credenciales, que van en cada request, y establecer un current_user si procede (si encuentra un usuario en nuestra BD y lo puede autenticar), con lo que conseguimos un sistema de autenticación rapido y ligero. Incluso si no queremos tener la autenticacion en el servidor web, con mandar las credenciales en cada peticion también nos valdria:
http://username:password@example.com
Asi a bote pronto, se me ocurre que es un método rápido para usar autenticación en cualquier tipo de API ligera.
Ultimamente me ha pasado también que a veces, tienes un site en staging o preprodución, con una autenticacion en tu apache, pero necesitas que ciertas acciones no lleven esa autenticación para poder hacer ciertas pruebas de una nueva feature, como por ejemplo, una nueva mega aplicación de facebook que has integrado dentro de tu aplicación rails, y quieres probar contra tu servidor de staging, para lo que necesitas dar acceso a ciertas acciones a las peticiones de facebook. Pues simplemente quitando la autenticacion del apache y con un before_filter se me ocurre que esto se podria conseguir facilmente:
before_filter :authorize_request
private
def authorize_request
return false unless current_user || params[:controller] == 'facebook_controller'
end
Si depués de todo ésto, decidís que viviríais mas tranquilos sin esta featura simplemente podéis desactivarla:
class UserSession < Authlogic::Session::Base
allow_http_basic_auth = false
end
Facebook empieza a dar los emails de sus usuarios a los desarrolladores
Publicado el 10 Feb 2010
Como anunció facebook en su blog para desarrolladores el pasado mes de enero, van a empezar a ceder el email de los usuarios a todas aquellas aplicaciones que lo solicten, previa autorización de los mismos.
Hasta ahora esto no era posible. Cuando desde un site se queria hacer una integración con facebook, através de facebook connect por ejemplo, se podia conseguir que los usuarios iniciaran una sesión valida en nuestro site através de las credenciales de facebook, pero en ningún caso podiamos enviar notificaciones a los usuarios a su email. El único canal existente para comunicarnos con los usuarios de facebook era através del proxied email donde dependias del propio facebook para hacer llegar tus notificaciones a los usuarios.
Ahora todo esto ha cambiado, y lo mejor de todo es que también funciona ;-). Através de un simple permiso llamado 'email' podemos solicitar a nuestros usuarios que compartan, incluso de manera obligatoria si así lo deseamos, su dirección de email en facebook con nuestro site.
A partir de ahora, podremos conseguir registrar a los usuarios en nuestro site de una manera mucho mas autónoma, sin tener que pedir campos adicionales una vez que se han logueado con facebook connect.
Para los desarrolladores de facebook bajo rails que usen el plugin facebooker ya pueden conseguir los email de los usuarios de la siguiente manera. Al inicializar facebook connect en nuestra vista, podemos pedir el permiso especial:
<%= init_fb_connect "XFBML" , :app_settings => {:permsToRequestOnConnect => "email"} %>
con lo que conseguiremos, que una vez el usuario haya hecho login en facebook, le salga la siguiente petición de permisos:
Una vez que el usuario ha aceptado los permisos, podemos acceder a su email con una simple FQL (Facebook Query Language:
"SELECT email FROM user WHERE uid='#{facebook_session.user.id}'";
o através del método directo de facebooker:
@user.email = facebook_session.user.email