Thursday, February 21, 2013

SCRUM: Metodología ágil


Hoy en día en cualquier proyecto resulta fundamental poder introducir cambios con rapidez y en cualquier fase del mismo. ¿Por qué? Pues ya sea por especificaciones del cliente o bien porque en mitad de un desarrollo nos dimos cuenta de que vamos por el camino equivocado.

Con esta idea de gestionar los proyectos de una manera ágil nació el concepto de SCRUM. En los años 80 los japoneses Takeuchi y Nonaka estudiaron las prácticas de empresas con buenos resultados de rapidez y flexibilidad en la producción: cámaras de fotos de Canon, fotocopiadoras de Xerox, automóviles de Honda, ordenadores de HP y otros.

Estas son algunas de las claves de SCRUM:

  1. Equipos pequeños y auto-organizados. Un equipo pequeño en el que los propios miembros se auto-organizan y entre los que existe una comunicación transparente hace que se sientan más cómodos, motivados y valorados.
  2. Historias de usuario. Teniendo en cuenta el punto de vista del usuario y del cliente se recogen los requisitos del producto que van a formar lo que se llama 'product backlog'. A cada una de las tareas que conforman esa lista se les asigna una prioridad
  3. Sprints. Conforma un período de tiempo corto que viene siendo de 2 a 4 semanas. Se trata de ver que tareas del backlog se van a llevar a cabo ('sprint backlog') con el objetivo de tener al final del sprint algo entregable y que funcione.
  4. Reuniones diarias. Se trata de que el equipo haga reuniones diarias que no van más alla de 10-15 minutos y en el que los miembros del equipo permanecen de pie para prestar la máxima atención posible. Se trata de que cada miembro del equipo responda de forma breve a 3 preguntas clave:
    • ¿Qué has hecho desde ayer?
    • ¿Qué tienes planeado hacer mañana? 
    • ¿Has encontrado algún problema para conseguir tu objetivo? 

Tuesday, February 19, 2013

Rails: Sass


Sass (Syntactically Awesome Stylesheets), es un meta-lenguaje que proporciona una sintaxis más simple y elegante para escribir CSS e implementa varias características útiles para la creación de hojas de estilo manejables.

Características


  1. Anidación. (seguir la filosofía DRY)
     .container{
          width: 200px;
     }
     .container .sms{
               border: 1px solid red;
     }
     .container .sms .title{
               color: red;
     }
     .container .section{
              margin-left:5px;
     }
     .container .section .title{
              color: #0000000;
    }
    
    .container{
        width: 200px;
        .sms {
              border: 1px solid red;
              .title { color: red;}
        }
       .section{
              margin-left:5px;
              .title{ color: #0000000;}
      }
  2. Variables. Las variables se declaran con el símbolo "$" y son muy útiles para declarar valores comunes en archivos CSS que son usadas en muchas partes del código. Podemos utilizar variables para representar los colores, tamaños, porcentajes...
    .content-navigation {
      border-color: #3bbfce;
      color: #2b9eab;
    }
    
    .border {
      padding: 8px;
      margin: 8px;
      border-color: #3bbfce;
    }
    
    $blue: #3bbfce;
    $margin: 8px;
    
    .content-navigation {
      border-color: $blue;
      color:
        darken($blue, 9%);
    }
    
    .border {
      padding: $margin;
      margin: $margin;
      border-color: $blue;
    }
    
    
  3.  Mixins. Un mixin es un fragmento de Sass que puede aplicarse fácilmente a otro selector, digamos que son como funciones. Para definir un mixin, todo lo que necesitas para escribir es @mixin, seguido por el nombre de la mixin y su estilo. uando se desea utilizar el mixin, sólo es llamarlo con la etiqueta @include.
    border-radius: 5px;  
    -moz-border-radius: 5px;  
    -webkit-border-radius: 5px;  
    
        @mixin rounded-corners {  
          border-radius: 5px;  
          -moz-border-radius: 5px;  
          -webkit-border-radius: 5px;  
        }  
         .content {  
          color: #FFF;  
          padding: 5px 12px;  
          margin: 10px 0;  
          font-size: 16px;  
          @include rounded-corners;  
        }  
    
  4. Herencia. Sass puede decir a un selector que herede todos los estilos de otro sin duplicar las propiedades CSS.
  5.  
    .error, .formError {
      border: 1px #f00;
      background: #fdd;
    }
    
    .formError {
      border-width: 3px;
    }
    
     
    .error {
      border: 1px #f00;
      background: #fdd;
    }
    
    .formError {
      @extend .error;
      border-width: 3px;
    }
    



    Friday, February 15, 2013

    Rails: Sitemap generator


    SitemapGenerator genera sitemaps para tu aplicación Rails.


    Instalación

    1. Añadir la línea gem 'sitemap_generator' al archivo Gemfile
    2. Ejecutar el comando rake sitemap:install
    Esto generará el archivo config/sitemap.rb que contiene la lógica para generar los ficheros sitemap.xml.


    Desarrollo

    SitemapGenerator::Sitemap.add_links do |sitemap|
    Article.find_each do |article|
      sitemap.add article_path(article), :lastmod => article.updated_at
    end
    end
    
    
    
    
    En este ejemplo se añadirán al sitemap las rutas referentes a artículos.

    Las opciones que se pueden añadir para cada url son las siguientes:

    1. priority La prioridad de una url respecto a otras de la web. Valores válidos: de 0.0 a 1.0. Default 0.5 
    2. changefreq Uno de: always, hourly, daily, weekly, monthly, yearly, never. Default weekly
    3. lastmod Fecha de última modificación. Default Time.now
    4. host Optional host for the link's URL. Defaults to default_host
    Una vez hecho esto si ejecutamos el comando rake -s sitemap:refresh los sitemaps serán generados en la carpeta public con la siguiente estructura de ficheros: sitemap_index.xml.gz, sitemap1.xml.gz, sitemap2.xml.gz, etc.

    Si queremos cambiar la carpeta donde guardar los sitemaps entonces bastará con añadir en el sitemap.rb la siguiente instrucción:

    
    
    
    
    SitemapGenerator::Sitemap.sitemaps_path = 'sitemaps/'
    
    


    Monday, February 11, 2013

    Rails: Observers


    En este patrón un objeto (el publicador o la fuente) informa a un conjunto de objetos interesados (los suscriptores) cuando su estado cambia.

    La clase ActiveRecord::Observer sigue un patrón Singleton. Este patrón garantiza que como máximo habrá una instancia de una clase.

    Los observadores de forma predeterminada se asignan a la clase con la que comparten un nombre. Así AuditoriaObserver estará ligado a la observación de auditoria. Si deseas asignar un nombre diferente a la clase a la que estás interesado en observar, puede utilizar el método de la clase Observer.observe ya sea a través de la clase concreta (Tweet) o un símbolo de esa clase (:tweet).

    Veámos un ejemplo para ver el comportamiento de este patrón:


    class AuditoriaObserver < ActiveRecord::Observer
    
      observe :tweet
      def after_create(auditoria)
        contact.logger.info('Nuevo tweet publicado!')
      end
    
      def after_destroy(auditoria)
        contact.logger.warn("Tweet con id: #{auditoria.id} fue borrado!")
      end
    end
    

    Como se puede ver en el ejemplo tenemos una clase Observer que observa a la clase Tweet, de tal manera que cuando se cree un objeto de este tipo o se borre tendremos constancia de ello.

    Estos métodos son callbacks que podrían ir perfectamente en la clase Tweet, pero el hacer uso de este tipo de patrones...nos permite extraer de los modelos todo ese código que no tiene que ver directamente con el modelo.

    Friday, February 01, 2013

    Rails: Eager Loading


    Una forma de mejorar el rendimiento en una aplicación es reducir el número de consultas SQL. Puedes hacer esto mediante una "precarga" o eager loading.

    Imaginemos que tenemos el siguiente modelo:
    
    
    
    class User < ActiveRecord::Base
      
       has_many :articles 
     
    end
    
    
    class Article < ActiveRecord::Base
      
       belongs_to :user
     
    end
    

    Si quisieramos pintar todos los articulos publicados en un periódico con la información del usuario que lo escribió, tendríamos algo similar a esto:
    @articles = Article.find(:all)
    
    @articles.each do |a|
      %p = a.title
      %p = a.user.name
    end
    
    El problema de esto es que si tenemos n articles estaríamos haciendo n accesos a base de datos para recuperar el user que lo escribió.
     

    Para evitar esto se puede usar precisamente el eager loading, es decir hacer una precarga de esos users, para luego no tener que acceder a base de datos. La solución sería la siguiente:

    @articles = Article.find(:all, :include => :users)
    

     Esto haría que además de acceder a la tabla articles hiciese una query de la forma:

    User Load (0.1ms)  SELECT `users`.* FROM `users` WHERE (`users`.article_id IN (1,2,3,4,5,6,7,8,9,10,50,102,103,28,101,16,25,22,78,80,84,86,88,89,99,105,107))


    Rails SQL Caching


    La forma en que funciona Rails SQL Caching es que las consultas se almacenan en caché durante la ejecución de una acción. Es importante observar que las memorias caché de consulta se crean en el inicio de una acción y son destruidas al final de esa acción y por lo tanto persiste sólo durante la ejecución de la acción.

    Puede ser que no deseemos este comportamiento, imaginemos que queremos sacar un usuario de manera aleatoria. Con el sql caching siempre obtendríamos los mismos resultados...


    User.find(:first, :order => "rand()") 



    Si queremos evitar que durante la acción el resultado siempre sea el mismo debemos hacer lo siguiente:



    class User < ActiveRecord::Base
      def self.usuario_aleatorio
        uncached do
          find(:first, :order => "rand()")
        end
      end
    end