Buenas Prácticas de desarrollo en Ruby on Rails
Upcoming SlideShare
Loading in...5
×
 

Buenas Prácticas de desarrollo en Ruby on Rails

on

  • 5,486 views

 

Statistics

Views

Total Views
5,486
Views on SlideShare
5,454
Embed Views
32

Actions

Likes
2
Downloads
49
Comments
0

3 Embeds 32

http://www.slideshare.net 24
http://iamserg.io 5
http://localhost 3

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Buenas Prácticas de desarrollo en Ruby on Rails Buenas Prácticas de desarrollo en Ruby on Rails Presentation Transcript

  • 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™