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

Tendances

Markup language classification, designing static and dynamic
Markup language classification, designing static and dynamicMarkup language classification, designing static and dynamic
Markup language classification, designing static and dynamic
Ankita Bhalla
 

Tendances (9)

Html and css
Html and cssHtml and css
Html and css
 
Css Specificity
Css SpecificityCss Specificity
Css Specificity
 
Introduction to HTML and CSS
Introduction to HTML and CSSIntroduction to HTML and CSS
Introduction to HTML and CSS
 
Html Slide Part-1
Html Slide Part-1Html Slide Part-1
Html Slide Part-1
 
HTML/CSS/java Script/Jquery
HTML/CSS/java Script/JqueryHTML/CSS/java Script/Jquery
HTML/CSS/java Script/Jquery
 
Dynamic CSS: Transforms, Transitions, and Animation Basics
Dynamic CSS: Transforms, Transitions, and Animation BasicsDynamic CSS: Transforms, Transitions, and Animation Basics
Dynamic CSS: Transforms, Transitions, and Animation Basics
 
CSS Font & Text style
CSS Font & Text style CSS Font & Text style
CSS Font & Text style
 
Introdução a HTML5
Introdução a HTML5Introdução a HTML5
Introdução a HTML5
 
Markup language classification, designing static and dynamic
Markup language classification, designing static and dynamicMarkup language classification, designing static and dynamic
Markup language classification, designing static and dynamic
 

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)
 
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
 

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

redes informaticas en una oficina administrativa
redes informaticas en una oficina administrativaredes informaticas en una oficina administrativa
redes informaticas en una oficina administrativa
nicho110
 

Dernier (11)

investigación de los Avances tecnológicos del siglo XXI
investigación de los Avances tecnológicos del siglo XXIinvestigación de los Avances tecnológicos del siglo XXI
investigación de los Avances tecnológicos del siglo XXI
 
Innovaciones tecnologicas en el siglo 21
Innovaciones tecnologicas en el siglo 21Innovaciones tecnologicas en el siglo 21
Innovaciones tecnologicas en el siglo 21
 
Avances tecnológicos del siglo XXI 10-07 eyvana
Avances tecnológicos del siglo XXI 10-07 eyvanaAvances tecnológicos del siglo XXI 10-07 eyvana
Avances tecnológicos del siglo XXI 10-07 eyvana
 
Avances tecnológicos del siglo XXI y ejemplos de estos
Avances tecnológicos del siglo XXI y ejemplos de estosAvances tecnológicos del siglo XXI y ejemplos de estos
Avances tecnológicos del siglo XXI y ejemplos de estos
 
Guia Basica para bachillerato de Circuitos Basicos
Guia Basica para bachillerato de Circuitos BasicosGuia Basica para bachillerato de Circuitos Basicos
Guia Basica para bachillerato de Circuitos Basicos
 
PROYECTO FINAL. Tutorial para publicar en SlideShare.pptx
PROYECTO FINAL. Tutorial para publicar en SlideShare.pptxPROYECTO FINAL. Tutorial para publicar en SlideShare.pptx
PROYECTO FINAL. Tutorial para publicar en SlideShare.pptx
 
How to use Redis with MuleSoft. A quick start presentation.
How to use Redis with MuleSoft. A quick start presentation.How to use Redis with MuleSoft. A quick start presentation.
How to use Redis with MuleSoft. A quick start presentation.
 
Resistencia extrema al cobre por un consorcio bacteriano conformado por Sulfo...
Resistencia extrema al cobre por un consorcio bacteriano conformado por Sulfo...Resistencia extrema al cobre por un consorcio bacteriano conformado por Sulfo...
Resistencia extrema al cobre por un consorcio bacteriano conformado por Sulfo...
 
EVOLUCION DE LA TECNOLOGIA Y SUS ASPECTOSpptx
EVOLUCION DE LA TECNOLOGIA Y SUS ASPECTOSpptxEVOLUCION DE LA TECNOLOGIA Y SUS ASPECTOSpptx
EVOLUCION DE LA TECNOLOGIA Y SUS ASPECTOSpptx
 
Buenos_Aires_Meetup_Redis_20240430_.pptx
Buenos_Aires_Meetup_Redis_20240430_.pptxBuenos_Aires_Meetup_Redis_20240430_.pptx
Buenos_Aires_Meetup_Redis_20240430_.pptx
 
redes informaticas en una oficina administrativa
redes informaticas en una oficina administrativaredes informaticas en una oficina administrativa
redes informaticas en una oficina administrativa
 

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™