SlideShare une entreprise Scribd logo
1  sur  100
Télécharger pour lire hors ligne
Buenas prácticas
de desarrollo en
 Ruby on Rails
Sergio Gil Pérez de la Manga
Súper Mega Disclaimer



 Todo el contenido de esta charla se
  basa en opiniones personalísimas
   del autor, salvo cuando se citen
expresamente las opiniones de otros
  autores, en cuyo caso se trata de
 interpretaciones personalísimas de
              las mismas
Súper Mega Disclaimer




Lo que tenga un asterisco gordo al
lado, es que no me lo he inventado
  (y está en la lista de referencias)
“Best Practice is an idea that asserts that
there is a technique, method, or process
  that is more e ective at delivering a
   particular outcome than any other
     technique, method or process”
“En el Go todas las piezas
 son iguales; en el Ajedrez,
son diferentes, y obedecen
a reglas de desplazamiento
  distintas, lo que complica
  el aprendizaje de la regla,
     pero facilita la tarea del
   debutante: un cuadro de
  juego codificado es de un
   uso más sencillo que una
    libertad completa con la
 que no se sabe qué hacer”

                  Pierre Aroutche ,
                            “El Go”
Cosas de las que no voy
 a hablar (por obvias)
TESTING
Código
 Buen
         fácil de
Código
         testear
Refactorizar sin
tests es un deporte
     de riesgo
Control de Versiones
Infórmate, participa, interactúa
LEE
LEE



Documentación
LEE



Documentación
    Blogs
LEE



Documentación
     Blogs
Listas de correo
ESCRIBE



Documentación
     Blogs
Listas de correo
Acude a Conferencias
Acude a Conferencias




 ¡Y habla si te dejan!
Ven a las quedadas
Haz pair programming si puedes
Hablemos de código
Conoce tus herramientas
some_things = []
some_other_things.each do |some_other_thing|
  some_things << some_other_thing.wadus
end
some_things = some_other_things.map do |some_other_thing|
  some_other_thing.wadus
end
some_things = some_other_things.map(&:wadus)
DRY pero no tanto
Don’t Repeat Yourself

  “Every piece of knowledge must have
   a single, unambiguous, authoritative
      representation within a system”
Pero DRY es un medio, no un fin
Pero DRY es un medio, no un fin
    Lo único importante es:
Pero DRY es un medio, no un fin
    Lo único importante es:
          Legibilidad
Pero DRY es un medio, no un fin
    Lo único importante es:
          Legibilidad
        Mantenibilidad
login: &login
                                   adapter: mysql
                                   username: username
                                   password: password
                                   host: mysql.example.com


Pero DRY es un medio, no un fin   development:
                                   <<: *login
    Lo único importante es:
                                   database: app_dev
          Legibilidad
        Mantenibilidad           test:
                                   <<: *login
                                   database: app_test

                                 production:
                                   <<: *login
                                   database: app_prod
MVC
Skinny Controller,
    Fat Model
Modelo cocinero,
controlador camarero
class Person < AR::B
  has_one :address
end




class PeopleController < AC
end




<% people = Person.find(
      :conditions => [quot;added_at > ? and deleted = ?quot;, Time.now.utc, false],
      :order => quot;last_name, first_namequot;) %>
<% people.reject { |p| p.address.nil? }.each do |person| %>
  <div class=quot;personquot;>
    <span class=quot;namequot;>
      <%= person.last_name %>, <%= person.first_name %>
    </span>
    <span class=quot;agequot;>
      <%= (Date.today - person.birthdate) / 365 %>
    </span>
  </div>
<% end %>
class Person < AR::B
  has_one :address
end




class PeopleController < AC
  def index
    @people = Person.find(
      :conditions => [quot;added_at > ? and deleted = ?quot;, Time.now.utc, false],
      :order => quot;last_name, first_namequot;)
    @people = @people.reject { |p| p.address.nil? }
  end
end



<% @people.each do |person| %>
  <div class=quot;personquot;>
    <span class=quot;namequot;>
      <%= person.last_name %>, <%= person.first_name %>
    </span>
    <span class=quot;agequot;>
      <%= (Date.today - person.birthdate) / 365 %>
    </span>
  </div>
<% end %>
class Person < ActiveRecord::Base
  has_one :address
  def self.find_recent
    people = find(
      :conditions => [quot;added_at > ? and deleted = ?quot;, Time.now.utc, false],
      :order => quot;last_name, first_namequot;)
    people.reject { |p| p.address.nil? }
  end
  def name
    quot;#{last_name}, #{first_name}quot;
  end
  def age
    (Date.today - person.birthdate) / 365
  end
end
class PeopleController < ActionController::Base
  def index
    @people = Person.find_recent
  end
end

<% @people.each do |person| %>
  <div class=quot;personquot;>
    <span class=quot;namequot;><%= person.name %></span>
    <span class=quot;agequot;><%= person.age %></span>
  </div>
<% end %>
Hacia el controlador trivial
Hacia el controlador trivial



Plugins como resource_controller
Hacia el controlador trivial



Plugins como resource_controller

     class PostsController < ApplicationController
       resource_controller
     end
REST
RESTricción liberadora
Si lo que quieres hacer no encaja en REST
Si lo que quieres hacer no encaja en REST




  •   Puede que pertenezca al 20% de
      cosas que no encajan
Si lo que quieres hacer no encaja en REST




  •   Puede que pertenezca al 20% de
      cosas que no encajan

  •   Puede que lo estés enfocando mal
Si lo que quieres hacer no encaja en REST




  •   Puede que pertenezca al 20% de
      cosas que no encajan

  •   Puede que lo estés enfocando mal

  •   Así que dale una vuelta
Demeter y el Acoplamiento
Un método de un objeto sólo
      debe llamar a:
Un método de un objeto sólo
      debe llamar a:


•   Métodos del mismo objeto
Un método de un objeto sólo
      debe llamar a:


•   Métodos del mismo objeto
•   Métodos de objetos
    directamente relacionados
comment.article.author.address.city.country.two_letter_code
class User < AR::B
  # email
end

class Blog < AR::B
  belongs_to :user
  has_many :articles
end

class Article < AR::B
  belongs_to :blog
end

article.blog.user.email
class User < AR::B
  # email
end

class Blog < AR::B
  belongs_to :user
  has_many :articles
  delegate :email, :to => :user
end

class Article < AR::B
  belongs_to :blog
  delegate :email, :to => :blog
end

article.email
El termómetro del test




before(:each) do
  @country = mock_model(Country, :two_letter_code => 'es')
  @city = mock_model(City, :country => @country)
  @address = mock_model(Address, :city => @city)
  @author = mock_model(User, :address => @address)
  @article = mock_model(Article, :author => @author)
  @comment = mock_model(Comment, :article => @article)
end

it quot;should have two_letter_code 'es'quot; do
  @comment.article.author.adress.city.country.two_letter_code.should == 'es'
end
El termómetro del test




before(:each) do
  @comment = mock_model(Comment, :author_country_code => 'es')
end

it quot;should have two_letter_code 'es'quot; do
  @comment.author_country_code.should == 'es'
end
Uso de convenciones
Las de Rails: piénsatelo antes de saltártelas
Crea las tuyas propias
Crea las tuyas propias
    ¡Y cúmplelas!
Refactorización
Refactoriza durante el desarrollo...
...y no al final
1. No refactorices y añadas
   funcionalidad a la vez
1. No refactorices y añadas
   funcionalidad a la vez

2. Haz tests antes de refactorizar.
   Y ejecútalos a menudo
1. No refactorices y añadas
   funcionalidad a la vez

2. Haz tests antes de refactorizar.
   Y ejecútalos a menudo

3. Refactoriza en pasos pequeños
Uso de variables
Minimizar uso de variables, y su scope

def show
  @post = Post.find(params[:id])
  @related_posts = Post.find(:all,
    :conditions => { :category_id => @post.category_id },
    :limit => 5)
end



<h2><%= @post.title %></h2>
<%= simple_format(@post.body) %>

<%- @recent_posts.each do |post| -%>
  ...
<%- end -%>
Minimizar uso de variables, y su scope

def show
  @post = Post.find(params[:id])
  @related_posts = @post.recent_posts
end




<h2><%= @post.title %></h2>
<%= simple_format(@post.body) %>

<%- @recent_posts.each do |post| -%>
  ...
<%- end -%>
Minimizar uso de variables, y su scope

def show
  @post = Post.find(params[:id])
end




<h2><%= @post.title %></h2>
<%= simple_format(@post.body) %>

<%- @post.recent_posts.each do |post| -%>
  ...
<%- end -%>
Minimizar uso de variables, y su scope
Minimizar uso de variables, y su scope


           Mi convención:
Minimizar uso de variables, y su scope


          Mi convención:
Una variable de instancia por acción
Minimizar uso de variables, y su scope


                Mi convención:
      Una variable de instancia por acción

•   Instancia de un
    modelo
Minimizar uso de variables, y su scope


                Mi convención:
      Una variable de instancia por acción

•   Instancia de un
    modelo
•   Nombrada como el
    modelo
Minimizar uso de variables, y su scope


                Mi convención:
      Una variable de instancia por acción

•   Instancia de un      •   Array de instancias
    modelo                   de un modelo
•   Nombrada como el
    modelo
Minimizar uso de variables, y su scope


                Mi convención:
      Una variable de instancia por acción

•   Instancia de un      •   Array de instancias
    modelo                   de un modelo
•   Nombrada como el     •   Nombrada como el
    modelo                   modelo en plural
El idioma del código
•   Se trata de
    intercambiar, ¿no?
•   Se trata de
    intercambiar, ¿no?

•   Rails hace un gran
    esfuerzo por acercarse
    al lenguaje humano. Si
    escribimos en
    spanglish, nos lo
    cargamos
•   Se trata de
    intercambiar, ¿no?

•   Rails hace un gran
    esfuerzo por acercarse
    al lenguaje humano. Si
    escribimos en
    spanglish, nos lo
    cargamos


    has_many :legajos
Recomendaciones bibliográficas
¿...?
Muchas Gracias


sgilperez@gmail.com
sergio@bebanjo.com
http://lacoctelera.com/porras
http://twitter.com/porras
Referencias




Pierre Aroutche , “El Go”
Andrew Hunt, Dave Thomas, “The Pragmatic Programmers”
Andrew Hunt, Venkat Subramaniam, “Practices of an Agile Developer”
Martin Fowler, “Refactoring: Improving the Design of Existing Code”
http://en.wikipedia.org/wiki/Best_practices
http://en.wikipedia.org/wiki/Law_of_Demeter
http://www.ccs.neu.edu/home/lieber/LoD.html
http://brian.maybeyoureinsane.net/blog/2006/12/15/law‐of‐demeter‐or‐how‐to‐avoid‐coding‐yourself‐into‐a‐corner‐in‐rails/
http://weblog.jamisbuck.org/2006/10/18/skinny‐controller‐fat‐model
http://c2.com/cgi/wiki?DontRepeatYourself
Enjuto Mojamuto en:
“Debuggeando una aplicación sin tests”
                     Caca
                    de bug

                        Como Se Fue Vino™

Contenu connexe

Similaire à Buenas Prácticas de desarrollo en Ruby on Rails

Html Y Javascript
Html Y JavascriptHtml Y Javascript
Html Y Javascript
oswchavez
 
Html Y Javascript
Html Y JavascriptHtml Y Javascript
Html Y Javascript
oswchavez
 
Conferencia Rails: Integracion Continua Y Rails
Conferencia Rails: Integracion Continua Y RailsConferencia Rails: Integracion Continua Y Rails
Conferencia Rails: Integracion Continua Y Rails
David Calavera
 
Trabajo final programacion
Trabajo final programacionTrabajo final programacion
Trabajo final programacion
markos1992
 
Accesibilidad web - más allá del marcado
Accesibilidad web - más allá del marcadoAccesibilidad web - más allá del marcado
Accesibilidad web - más allá del marcado
Manuel Razzari
 
Conceptos de algoritmo, programa y lenguaje de
Conceptos de algoritmo, programa y lenguaje deConceptos de algoritmo, programa y lenguaje de
Conceptos de algoritmo, programa y lenguaje de
'Felipe Lozada
 
Conceptos de algoritmo, programa y lenguaje de
Conceptos de algoritmo, programa y lenguaje deConceptos de algoritmo, programa y lenguaje de
Conceptos de algoritmo, programa y lenguaje de
'Felipe Lozada
 
Conceptos de algoritmo, programa y lenguaje de
Conceptos de algoritmo, programa y lenguaje deConceptos de algoritmo, programa y lenguaje de
Conceptos de algoritmo, programa y lenguaje de
'Felipe Lozada
 
Conceptos de algoritmo, programa y lenguaje de
Conceptos de algoritmo, programa y lenguaje deConceptos de algoritmo, programa y lenguaje de
Conceptos de algoritmo, programa y lenguaje de
'Felipe Lozada
 

Similaire à Buenas Prácticas de desarrollo en Ruby on Rails (20)

Descubriendo Ruby On Rails (Desarrollo Agil De Aplicaciones Web)
Descubriendo Ruby On Rails (Desarrollo Agil De Aplicaciones Web)Descubriendo Ruby On Rails (Desarrollo Agil De Aplicaciones Web)
Descubriendo Ruby On Rails (Desarrollo Agil De Aplicaciones Web)
 
Rhodes: Framework Open Source para desarrollo móvil multiplataforma
Rhodes: Framework Open Source para desarrollo móvil multiplataformaRhodes: Framework Open Source para desarrollo móvil multiplataforma
Rhodes: Framework Open Source para desarrollo móvil multiplataforma
 
Encuentro Linux 2011
Encuentro Linux 2011Encuentro Linux 2011
Encuentro Linux 2011
 
Html Y Javascript
Html Y JavascriptHtml Y Javascript
Html Y Javascript
 
Html Y Javascript
Html Y JavascriptHtml Y Javascript
Html Y Javascript
 
Conferencia Rails: Integracion Continua Y Rails
Conferencia Rails: Integracion Continua Y RailsConferencia Rails: Integracion Continua Y Rails
Conferencia Rails: Integracion Continua Y Rails
 
Introducción Nivelación PHP
Introducción Nivelación PHPIntroducción Nivelación PHP
Introducción Nivelación PHP
 
Metadata api en apex
Metadata api en apexMetadata api en apex
Metadata api en apex
 
Trabajo final programacion
Trabajo final programacionTrabajo final programacion
Trabajo final programacion
 
Seguridad En Programación
Seguridad En ProgramaciónSeguridad En Programación
Seguridad En Programación
 
Django: el framework web definitivo
Django: el framework web definitivoDjango: el framework web definitivo
Django: el framework web definitivo
 
Php Basico
Php BasicoPhp Basico
Php Basico
 
Primeros pasos Symfony PHPVigo
Primeros pasos Symfony PHPVigoPrimeros pasos Symfony PHPVigo
Primeros pasos Symfony PHPVigo
 
Javascript
JavascriptJavascript
Javascript
 
Accesibilidad web - más allá del marcado
Accesibilidad web - más allá del marcadoAccesibilidad web - más allá del marcado
Accesibilidad web - más allá del marcado
 
Conceptos de algoritmo, programa y lenguaje de
Conceptos de algoritmo, programa y lenguaje deConceptos de algoritmo, programa y lenguaje de
Conceptos de algoritmo, programa y lenguaje de
 
Conceptos de algoritmo, programa y lenguaje de
Conceptos de algoritmo, programa y lenguaje deConceptos de algoritmo, programa y lenguaje de
Conceptos de algoritmo, programa y lenguaje de
 
Conceptos de algoritmo, programa y lenguaje de
Conceptos de algoritmo, programa y lenguaje deConceptos de algoritmo, programa y lenguaje de
Conceptos de algoritmo, programa y lenguaje de
 
Conceptos de algoritmo, programa y lenguaje de
Conceptos de algoritmo, programa y lenguaje deConceptos de algoritmo, programa y lenguaje de
Conceptos de algoritmo, programa y lenguaje de
 
Workflows On Rails
Workflows On RailsWorkflows On Rails
Workflows On Rails
 

Plus de Sergio Gil (9)

Five Languages in a Moment
Five Languages in a MomentFive Languages in a Moment
Five Languages in a Moment
 
A [git] workflow
A [git] workflowA [git] workflow
A [git] workflow
 
The Total IDE
The Total IDEThe Total IDE
The Total IDE
 
Acceptance testing with Steak and Capybara
Acceptance testing with Steak and CapybaraAcceptance testing with Steak and Capybara
Acceptance testing with Steak and Capybara
 
El Desarrollador Total
El Desarrollador TotalEl Desarrollador Total
El Desarrollador Total
 
Metaprogramación (en Ruby): programas que escriben programas
Metaprogramación (en Ruby): programas que escriben programasMetaprogramación (en Ruby): programas que escriben programas
Metaprogramación (en Ruby): programas que escriben programas
 
Más allá del testing
Más allá del testingMás allá del testing
Más allá del testing
 
Ruby on Rails
Ruby on RailsRuby on Rails
Ruby on Rails
 
Ruby Mola (y por qué)
Ruby Mola (y por qué)Ruby Mola (y por qué)
Ruby Mola (y por qué)
 

Dernier

Dernier (20)

JORNADA INTELIGENCIA ARTIFICIAL Y REALIDAD VIRTUAL
JORNADA INTELIGENCIA ARTIFICIAL Y REALIDAD VIRTUALJORNADA INTELIGENCIA ARTIFICIAL Y REALIDAD VIRTUAL
JORNADA INTELIGENCIA ARTIFICIAL Y REALIDAD VIRTUAL
 
Unidad 1- Historia y Evolucion de las computadoras.pdf
Unidad 1- Historia y Evolucion de las computadoras.pdfUnidad 1- Historia y Evolucion de las computadoras.pdf
Unidad 1- Historia y Evolucion de las computadoras.pdf
 
BUSCADORES DE INTERNET (Universidad de Sonora).
BUSCADORES DE INTERNET (Universidad de Sonora).BUSCADORES DE INTERNET (Universidad de Sonora).
BUSCADORES DE INTERNET (Universidad de Sonora).
 
Imágenes digitales: Calidad de la información
Imágenes digitales: Calidad de la informaciónImágenes digitales: Calidad de la información
Imágenes digitales: Calidad de la información
 
CIBERSEGURIDAD Y SEGURIDAD INFORMATICA .
CIBERSEGURIDAD Y SEGURIDAD INFORMATICA .CIBERSEGURIDAD Y SEGURIDAD INFORMATICA .
CIBERSEGURIDAD Y SEGURIDAD INFORMATICA .
 
Desarrollo del Dominio del Internet - Estrada
Desarrollo del Dominio del Internet - EstradaDesarrollo del Dominio del Internet - Estrada
Desarrollo del Dominio del Internet - Estrada
 
PRÁCTICA Nº 4: “Análisis de secuencias del ADN con el software BioEdit y uso ...
PRÁCTICA Nº 4: “Análisis de secuencias del ADN con el software BioEdit y uso ...PRÁCTICA Nº 4: “Análisis de secuencias del ADN con el software BioEdit y uso ...
PRÁCTICA Nº 4: “Análisis de secuencias del ADN con el software BioEdit y uso ...
 
Gestión de concurrencia y bloqueos en SQL Server
Gestión de concurrencia y bloqueos en SQL ServerGestión de concurrencia y bloqueos en SQL Server
Gestión de concurrencia y bloqueos en SQL Server
 
Pons, A. - El desorden digital - guia para historiadores y humanistas [2013].pdf
Pons, A. - El desorden digital - guia para historiadores y humanistas [2013].pdfPons, A. - El desorden digital - guia para historiadores y humanistas [2013].pdf
Pons, A. - El desorden digital - guia para historiadores y humanistas [2013].pdf
 
NIVEL DE MADUREZ TECNOLÓGICA (TRL).pptx
NIVEL DE  MADUREZ TECNOLÓGICA (TRL).pptxNIVEL DE  MADUREZ TECNOLÓGICA (TRL).pptx
NIVEL DE MADUREZ TECNOLÓGICA (TRL).pptx
 
Ejercicio 1 periodo 2 de Tecnología 2024
Ejercicio 1 periodo 2 de Tecnología 2024Ejercicio 1 periodo 2 de Tecnología 2024
Ejercicio 1 periodo 2 de Tecnología 2024
 
TELECOMUNICACIONES- CAPITULO2: Modelo Osi ccna
TELECOMUNICACIONES- CAPITULO2: Modelo Osi ccnaTELECOMUNICACIONES- CAPITULO2: Modelo Osi ccna
TELECOMUNICACIONES- CAPITULO2: Modelo Osi ccna
 
Uso de las TIC en la vida cotidiana .
Uso de las TIC en la vida cotidiana       .Uso de las TIC en la vida cotidiana       .
Uso de las TIC en la vida cotidiana .
 
Presentacion y Extension de tema para Blogger.pptx
Presentacion y Extension de tema para Blogger.pptxPresentacion y Extension de tema para Blogger.pptx
Presentacion y Extension de tema para Blogger.pptx
 
Navegadores de internet - Nuevas Tecnologías de la Información y la Comunicación
Navegadores de internet - Nuevas Tecnologías de la Información y la ComunicaciónNavegadores de internet - Nuevas Tecnologías de la Información y la Comunicación
Navegadores de internet - Nuevas Tecnologías de la Información y la Comunicación
 
taller de tablas en word para estudiantes de secundaria
taller de tablas en word para estudiantes de secundariataller de tablas en word para estudiantes de secundaria
taller de tablas en word para estudiantes de secundaria
 
Tipos de datos en Microsoft Access de Base de Datos
Tipos de datos en Microsoft Access de Base de DatosTipos de datos en Microsoft Access de Base de Datos
Tipos de datos en Microsoft Access de Base de Datos
 
proyectos_social_y_socioproductivos _mapas_conceptuales
proyectos_social_y_socioproductivos _mapas_conceptualesproyectos_social_y_socioproductivos _mapas_conceptuales
proyectos_social_y_socioproductivos _mapas_conceptuales
 
¡Mira mi nuevo diseño hecho en Canva!.pdf
¡Mira mi nuevo diseño hecho en Canva!.pdf¡Mira mi nuevo diseño hecho en Canva!.pdf
¡Mira mi nuevo diseño hecho en Canva!.pdf
 
HerramientasInformaticas ¿Que es? - ¿Para que sirve? - Recomendaciones - Comp...
HerramientasInformaticas ¿Que es? - ¿Para que sirve? - Recomendaciones - Comp...HerramientasInformaticas ¿Que es? - ¿Para que sirve? - Recomendaciones - Comp...
HerramientasInformaticas ¿Que es? - ¿Para que sirve? - Recomendaciones - Comp...
 

Buenas Prácticas de desarrollo en Ruby on Rails

  • 1. Buenas prácticas de desarrollo en Ruby on Rails Sergio Gil Pérez de la Manga
  • 2. Súper Mega Disclaimer Todo el contenido de esta charla se basa en opiniones personalísimas del autor, salvo cuando se citen expresamente las opiniones de otros autores, en cuyo caso se trata de interpretaciones personalísimas de las mismas
  • 3. Súper Mega Disclaimer Lo que tenga un asterisco gordo al lado, es que no me lo he inventado (y está en la lista de referencias)
  • 4. “Best Practice is an idea that asserts that there is a technique, method, or process that is more e ective at delivering a particular outcome than any other technique, method or process”
  • 5.
  • 6.
  • 7. “En el Go todas las piezas son iguales; en el Ajedrez, son diferentes, y obedecen a reglas de desplazamiento distintas, lo que complica el aprendizaje de la regla, pero facilita la tarea del debutante: un cuadro de juego codificado es de un uso más sencillo que una libertad completa con la que no se sabe qué hacer” Pierre Aroutche , “El Go”
  • 8. Cosas de las que no voy a hablar (por obvias)
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 15. Código Buen fácil de Código testear
  • 16. Refactorizar sin tests es un deporte de riesgo
  • 19. LEE
  • 22. LEE Documentación Blogs Listas de correo
  • 23. ESCRIBE Documentación Blogs Listas de correo
  • 25. Acude a Conferencias ¡Y habla si te dejan!
  • 26.
  • 27. Ven a las quedadas
  • 28. Haz pair programming si puedes
  • 31. some_things = [] some_other_things.each do |some_other_thing| some_things << some_other_thing.wadus end
  • 32. some_things = some_other_things.map do |some_other_thing| some_other_thing.wadus end
  • 34. DRY pero no tanto
  • 35. Don’t Repeat Yourself “Every piece of knowledge must have a single, unambiguous, authoritative representation within a system”
  • 36. Pero DRY es un medio, no un fin
  • 37. Pero DRY es un medio, no un fin Lo único importante es:
  • 38. Pero DRY es un medio, no un fin Lo único importante es: Legibilidad
  • 39. Pero DRY es un medio, no un fin Lo único importante es: Legibilidad Mantenibilidad
  • 40. login: &login adapter: mysql username: username password: password host: mysql.example.com Pero DRY es un medio, no un fin development: <<: *login Lo único importante es: database: app_dev Legibilidad Mantenibilidad test: <<: *login database: app_test production: <<: *login database: app_prod
  • 41. MVC
  • 42.
  • 43. Skinny Controller, Fat Model
  • 45. class Person < AR::B has_one :address end class PeopleController < AC end <% people = Person.find( :conditions => [quot;added_at > ? and deleted = ?quot;, Time.now.utc, false], :order => quot;last_name, first_namequot;) %> <% people.reject { |p| p.address.nil? }.each do |person| %> <div class=quot;personquot;> <span class=quot;namequot;> <%= person.last_name %>, <%= person.first_name %> </span> <span class=quot;agequot;> <%= (Date.today - person.birthdate) / 365 %> </span> </div> <% end %>
  • 46. class Person < AR::B has_one :address end class PeopleController < AC def index @people = Person.find( :conditions => [quot;added_at > ? and deleted = ?quot;, Time.now.utc, false], :order => quot;last_name, first_namequot;) @people = @people.reject { |p| p.address.nil? } end end <% @people.each do |person| %> <div class=quot;personquot;> <span class=quot;namequot;> <%= person.last_name %>, <%= person.first_name %> </span> <span class=quot;agequot;> <%= (Date.today - person.birthdate) / 365 %> </span> </div> <% end %>
  • 47. class Person < ActiveRecord::Base has_one :address def self.find_recent people = find( :conditions => [quot;added_at > ? and deleted = ?quot;, Time.now.utc, false], :order => quot;last_name, first_namequot;) people.reject { |p| p.address.nil? } end def name quot;#{last_name}, #{first_name}quot; end def age (Date.today - person.birthdate) / 365 end end class PeopleController < ActionController::Base def index @people = Person.find_recent end end <% @people.each do |person| %> <div class=quot;personquot;> <span class=quot;namequot;><%= person.name %></span> <span class=quot;agequot;><%= person.age %></span> </div> <% end %>
  • 49. Hacia el controlador trivial Plugins como resource_controller
  • 50. Hacia el controlador trivial Plugins como resource_controller class PostsController < ApplicationController resource_controller end
  • 51. REST
  • 53. Si lo que quieres hacer no encaja en REST
  • 54. Si lo que quieres hacer no encaja en REST • Puede que pertenezca al 20% de cosas que no encajan
  • 55. Si lo que quieres hacer no encaja en REST • Puede que pertenezca al 20% de cosas que no encajan • Puede que lo estés enfocando mal
  • 56. Si lo que quieres hacer no encaja en REST • Puede que pertenezca al 20% de cosas que no encajan • Puede que lo estés enfocando mal • Así que dale una vuelta
  • 57. Demeter y el Acoplamiento
  • 58. Un método de un objeto sólo debe llamar a:
  • 59. Un método de un objeto sólo debe llamar a: • Métodos del mismo objeto
  • 60. Un método de un objeto sólo debe llamar a: • Métodos del mismo objeto • Métodos de objetos directamente relacionados
  • 62. class User < AR::B # email end class Blog < AR::B belongs_to :user has_many :articles end class Article < AR::B belongs_to :blog end article.blog.user.email
  • 63. class User < AR::B # email end class Blog < AR::B belongs_to :user has_many :articles delegate :email, :to => :user end class Article < AR::B belongs_to :blog delegate :email, :to => :blog end article.email
  • 64. El termómetro del test before(:each) do @country = mock_model(Country, :two_letter_code => 'es') @city = mock_model(City, :country => @country) @address = mock_model(Address, :city => @city) @author = mock_model(User, :address => @address) @article = mock_model(Article, :author => @author) @comment = mock_model(Comment, :article => @article) end it quot;should have two_letter_code 'es'quot; do @comment.article.author.adress.city.country.two_letter_code.should == 'es' end
  • 65. El termómetro del test before(:each) do @comment = mock_model(Comment, :author_country_code => 'es') end it quot;should have two_letter_code 'es'quot; do @comment.author_country_code.should == 'es' end
  • 67. Las de Rails: piénsatelo antes de saltártelas
  • 68.
  • 69. Crea las tuyas propias
  • 70. Crea las tuyas propias ¡Y cúmplelas!
  • 72. Refactoriza durante el desarrollo...
  • 73. ...y no al final
  • 74.
  • 75. 1. No refactorices y añadas funcionalidad a la vez
  • 76. 1. No refactorices y añadas funcionalidad a la vez 2. Haz tests antes de refactorizar. Y ejecútalos a menudo
  • 77. 1. No refactorices y añadas funcionalidad a la vez 2. Haz tests antes de refactorizar. Y ejecútalos a menudo 3. Refactoriza en pasos pequeños
  • 79. Minimizar uso de variables, y su scope def show @post = Post.find(params[:id]) @related_posts = Post.find(:all, :conditions => { :category_id => @post.category_id }, :limit => 5) end <h2><%= @post.title %></h2> <%= simple_format(@post.body) %> <%- @recent_posts.each do |post| -%> ... <%- end -%>
  • 80. Minimizar uso de variables, y su scope def show @post = Post.find(params[:id]) @related_posts = @post.recent_posts end <h2><%= @post.title %></h2> <%= simple_format(@post.body) %> <%- @recent_posts.each do |post| -%> ... <%- end -%>
  • 81. Minimizar uso de variables, y su scope def show @post = Post.find(params[:id]) end <h2><%= @post.title %></h2> <%= simple_format(@post.body) %> <%- @post.recent_posts.each do |post| -%> ... <%- end -%>
  • 82. Minimizar uso de variables, y su scope
  • 83. Minimizar uso de variables, y su scope Mi convención:
  • 84. Minimizar uso de variables, y su scope Mi convención: Una variable de instancia por acción
  • 85. Minimizar uso de variables, y su scope Mi convención: Una variable de instancia por acción • Instancia de un modelo
  • 86. Minimizar uso de variables, y su scope Mi convención: Una variable de instancia por acción • Instancia de un modelo • Nombrada como el modelo
  • 87. Minimizar uso de variables, y su scope Mi convención: Una variable de instancia por acción • Instancia de un • Array de instancias modelo de un modelo • Nombrada como el modelo
  • 88. Minimizar uso de variables, y su scope Mi convención: Una variable de instancia por acción • Instancia de un • Array de instancias modelo de un modelo • Nombrada como el • Nombrada como el modelo modelo en plural
  • 89. El idioma del código
  • 90.
  • 91. Se trata de intercambiar, ¿no?
  • 92. Se trata de intercambiar, ¿no? • Rails hace un gran esfuerzo por acercarse al lenguaje humano. Si escribimos en spanglish, nos lo cargamos
  • 93. Se trata de intercambiar, ¿no? • Rails hace un gran esfuerzo por acercarse al lenguaje humano. Si escribimos en spanglish, nos lo cargamos has_many :legajos
  • 95.
  • 96.
  • 99. Referencias Pierre Aroutche , “El Go” Andrew Hunt, Dave Thomas, “The Pragmatic Programmers” Andrew Hunt, Venkat Subramaniam, “Practices of an Agile Developer” Martin Fowler, “Refactoring: Improving the Design of Existing Code” http://en.wikipedia.org/wiki/Best_practices http://en.wikipedia.org/wiki/Law_of_Demeter http://www.ccs.neu.edu/home/lieber/LoD.html http://brian.maybeyoureinsane.net/blog/2006/12/15/law‐of‐demeter‐or‐how‐to‐avoid‐coding‐yourself‐into‐a‐corner‐in‐rails/ http://weblog.jamisbuck.org/2006/10/18/skinny‐controller‐fat‐model http://c2.com/cgi/wiki?DontRepeatYourself
  • 100. Enjuto Mojamuto en: “Debuggeando una aplicación sin tests” Caca de bug Como Se Fue Vino™