Your SlideShare is downloading. ×
0
Una Critica a Rails by Luca Guidi
Una Critica a Rails by Luca Guidi
Una Critica a Rails by Luca Guidi
Una Critica a Rails by Luca Guidi
Una Critica a Rails by Luca Guidi
Una Critica a Rails by Luca Guidi
Una Critica a Rails by Luca Guidi
Una Critica a Rails by Luca Guidi
Una Critica a Rails by Luca Guidi
Una Critica a Rails by Luca Guidi
Una Critica a Rails by Luca Guidi
Una Critica a Rails by Luca Guidi
Una Critica a Rails by Luca Guidi
Una Critica a Rails by Luca Guidi
Una Critica a Rails by Luca Guidi
Una Critica a Rails by Luca Guidi
Una Critica a Rails by Luca Guidi
Una Critica a Rails by Luca Guidi
Una Critica a Rails by Luca Guidi
Una Critica a Rails by Luca Guidi
Una Critica a Rails by Luca Guidi
Una Critica a Rails by Luca Guidi
Una Critica a Rails by Luca Guidi
Una Critica a Rails by Luca Guidi
Una Critica a Rails by Luca Guidi
Una Critica a Rails by Luca Guidi
Una Critica a Rails by Luca Guidi
Una Critica a Rails by Luca Guidi
Una Critica a Rails by Luca Guidi
Una Critica a Rails by Luca Guidi
Una Critica a Rails by Luca Guidi
Una Critica a Rails by Luca Guidi
Una Critica a Rails by Luca Guidi
Una Critica a Rails by Luca Guidi
Una Critica a Rails by Luca Guidi
Una Critica a Rails by Luca Guidi
Una Critica a Rails by Luca Guidi
Una Critica a Rails by Luca Guidi
Una Critica a Rails by Luca Guidi
Una Critica a Rails by Luca Guidi
Una Critica a Rails by Luca Guidi
Una Critica a Rails by Luca Guidi
Una Critica a Rails by Luca Guidi
Una Critica a Rails by Luca Guidi
Una Critica a Rails by Luca Guidi
Una Critica a Rails by Luca Guidi
Una Critica a Rails by Luca Guidi
Una Critica a Rails by Luca Guidi
Una Critica a Rails by Luca Guidi
Una Critica a Rails by Luca Guidi
Una Critica a Rails by Luca Guidi
Una Critica a Rails by Luca Guidi
Una Critica a Rails by Luca Guidi
Una Critica a Rails by Luca Guidi
Una Critica a Rails by Luca Guidi
Una Critica a Rails by Luca Guidi
Una Critica a Rails by Luca Guidi
Una Critica a Rails by Luca Guidi
Una Critica a Rails by Luca Guidi
Una Critica a Rails by Luca Guidi
Una Critica a Rails by Luca Guidi
Una Critica a Rails by Luca Guidi
Una Critica a Rails by Luca Guidi
Una Critica a Rails by Luca Guidi
Una Critica a Rails by Luca Guidi
Una Critica a Rails by Luca Guidi
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Una Critica a Rails by Luca Guidi

918

Published on

Un profondo punto di vista sul perché Ruby on Rails ha rivoluzionato lo sviluppo web. …

Un profondo punto di vista sul perché Ruby on Rails ha rivoluzionato lo sviluppo web.

Questo talk focalizzerà la sua attenzione sul “Golden Path” di Rails, sui motivi del suo successo, sui problemi più comuni, e su come le sue API possano essere migliorate.

Impareremo a trarre beneficio da uno strumento tanto potente quanto pericoloso, di come mitigare le implicazioni architetturali, di design e testabilità delle vostre applicazioni, migliorando la qualità del codice..

Published in: Technology, Education
0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
918
On Slideshare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
2
Comments
0
Likes
2
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. March 22nd, 2013A Rails Criticismhow i learned to stop worrying about the Golden Path Luca Guidi
  • 2. AGENDAintro
  • 3. Luca Guidi Senior Developer at Litmus @jodosha - http//lucag uidi.com
  • 4. litmusBeautiful Email previews Campaig n analytics Spam filter tests HTML code analysis And many other..
  • 5. Why Railshas revolutionized web development? (IMHO)
  • 6. Why Rails has revolutionized web development?Convention Over Config uration (IMHO) :)
  • 7. Why Rails has revolutionized web development?Dynamic and innovative Convention Over Config uration ecosystem (IMHO) :)
  • 8. Why Rails has revolutionized web development?Dynamic and innovative Convention Over Productivity and Developer uration Config Happiness ecosystem (IMHO) :)
  • 9. ..butThe Framework is almost ten years old
  • 10. ..butTheLot of Legacy Code A Framework is almost ten years old is around
  • 11. ..butTheLot of Legacymajor A Frameworkais Code Upgrades to almost release years old ten are *painful* is around
  • 12. AGENDAintro problems
  • 13. Active RecordActiveRecord
  • 14. Active RecordModels != Records
  • 15. Active Record Encapsulation violations1 if article.statearticle.published? 1 unless != published2 article.update_attribute(state: published) 2 article.publish!3 end 3 end 4 # not completely right...
  • 16. Active Record Encapsulation violations1 if article.statearticle.published? 1 unless != published2 article.update_attribute(state: published) 2 article.publish!3 end 3 end 4 # not completely right...
  • 17. Active Record Encapsulation violations1 if article.statearticle.published? 1 unless != published2 article.update_attribute(state: published) 2 article.publish!3 end 3 end 4 # not completely right...
  • 18. Active Record Tell, Don’t Ask12 violations article.publish! unless article.published? # article.publish! push the implementation3 end # into the model4 # not completely right...
  • 19. Active Record Tell, Don’t Ask violations1 article.publish! unless article.published?2 # article.publish! push the implementation3 end # into the model4 # not completely right...
  • 20. Active Record Tell, Don’t Ask violations1 article.publish! unless article.published?2 # article.publish! push the implementation3 end # into the model4 # not completely right...
  • 21. Active Record2 Implicit vs Explicit API1 class Post < ActiveRecord::Base 1 Post.where(state:published). 1 Post.most_recent_published def self.most_recent_published(limit = 5)3 2published.recent(limit).order(created_at DESC) order(created_at DESC).4 end5 3 limit(5)6 private7 scope :published, ->() { where(state: published) }8 scope :recent, ->(n) { limit(n) }9 end
  • 22. Active Record Implicit vs Explicit API1 class Post < ActiveRecord::Base2 1 Post.where(state:published). 1 Post.most_recent_published def self.most_recent_published(limit = 5)3 2published.recent(limit).order(created_at DESC) order(created_at DESC).4 end5 3 limit(5)6 private7 scope :published, ->() { where(state: published) }8 scope :recent, ->(n) { limit(n) }9 end
  • 23. Active Record Implicit vs Explicit API1 class Post < ActiveRecord::Base2 1 Post.where(state:published). 1 Post.most_recent_published def self.most_recent_published(limit = 5)3 2published.recent(limit).order(created_at DESC) order(created_at DESC).4 end5 3 limit(5)6 private7 scope :published, ->() { where(state: published) }8 scope :recent, ->(n) { limit(n) }9 end
  • 24. Active Record Implicit vs Explicit API1 class Post < ActiveRecord::Base2 1 Post.where(state:published). 1 Post.most_recent_published def self.most_recent_published(limit = 5)3 2published.recent(limit).order(created_at DESC) order(created_at DESC).4 end5 3 limit(5)6 private7 scope :published, ->() { where(state: published) }8 scope :recent, ->(n) { limit(n) }9 end
  • 25. Active RecordCallbacks abuse Non-persistence logic is tight to the persistence life cycle. Eg. Sending emails
  • 26. Active RecordTestability issues Micheal Feathers
  • 27. Active RecordA test is not a unit test if it talks Testability issues to a database. Micheal Feathers
  • 28. Action Controller ActionController It doesn’t affect too much your architecture, but it has strange OOP design.
  • 29. Action Controller1 class PostsController < ApplicationController2 before_filter :authenticate Frankenstein Controllers34 def new5 end67 def create8 @post = Post.new(params[:post])910 if @post.save11 redirect_to post_url(@post), notice: Yay!12 else13 render :new14 end15 end16 end
  • 30. Action Controller Frankenstein Controllers1 class PostsController < ApplicationController2 before_filter :authenticate34 def new5 end67 def create8 @post = Post.new(params[:post])910 if @post.save11 redirect_to post_url(@post), notice: Yay!12 else13 render :new14 end15 end16 end
  • 31. Action Controller Frankenstein Controllers1 class PostsController < ApplicationController2 before_filter :authenticate34 def new5 end67 def create8 @post = Post.new(params[:post])910 if @post.save11 redirect_to post_url(@post), notice: Yay!12 else13 render :new14 end15 end16 end
  • 32. Action Controller Frankenstein Controllers1 class PostsController < ApplicationController2 before_filter :authenticate34 def new5 end67 def create8 @post = Post.new(params[:post])910 if @post.save11 redirect_to post_url(@post), notice: Yay!12 else13 render :new14 end15 end16 end
  • 33. Action Controller Frankenstein Controllers1 class PostsController < ApplicationController2 before_filter :authenticate34 def new5 end67 def create8 @post = Post.new(params[:post])910 if @post.save11 redirect_to post_url(@post), notice: Yay!12 else13 render :new14 end15 end16 end
  • 34. Action Controller Frankenstein Controllers1 class PostsController < ApplicationController2 before_filter :authenticate34 def new5 end67 def create8 @post = Post.new(params[:post])910 if @post.save11 redirect_to post_url(@post), notice: Yay!12 else13 render :new14 end15 end16 end
  • 35. Action Controller1 class PostsController < ApplicationController2 # ... Odd classes34 def create5 @post = Post.new(params[:post])67 if @post.save8 # ...9 else10 # ...11 end12 end13 end
  • 36. Action Controller Odd classes1 class PostsController < ApplicationController2 # ...34 def create5 @post = Post.new(params[:post])67 if @post.save8 # ...9 else10 # ...11 end12 end13 end
  • 37. Action Controller Odd classes1 class PostsController < ApplicationController2 # ...34 def create5 @post = Post.new(params[:post])67 if @post.save8 # ...9 else10 # ...11 end12 end13 end
  • 38. Action Controller Odd classes1 class PostsController < ApplicationController2 # ...34 def create5 @post = Post.new(params[:post])67 if @post.save8 # ...9 else10 # ...11 end12 end13 end
  • 39. Action Controller34 Encapsulation violations1 class PostsController < ApplicationController2 # ... def create5 @post = Post.new(params[:post])6 # ...7 end8 end
  • 40. Action Controller Encapsulation violations1 class PostsController < ApplicationController2 # ...34 def create5 @post = Post.new(params[:post])6 # ...7 end8 end
  • 41. Action Controller1 describe PostsController do Testability issues2 it assigns @posts do3 Post.should_receive(:most_recent_published).4 and_return(posts = [mock])5 get :index67 expect(assigns(:posts)).to eq(posts)8 end9 end
  • 42. Action Controller Testability issues1 describe PostsController do2 it assigns @posts do3 Post.should_receive(:most_recent_published).4 and_return(posts = [mock])5 get :index67 expect(assigns(:posts)).to eq(posts)8 end9 end
  • 43. Action Controller Testability issues1 describe PostsController do2 it assigns @posts do3 Post.should_receive(:most_recent_published).4 and_return(posts = [mock])5 get :index67 expect(assigns(:posts)).to eq(posts)8 end9 end
  • 44. Action Controller Testability issues1 describe PostsController do2 it assigns @posts do3 Post.should_receive(:most_recent_published).4 and_return(posts = [mock])5 get :index67 expect(assigns(:posts)).to eq(posts)8 end9 end
  • 45. Action Controller Testability issues1 describe PostsController do2 it assigns @posts do3 Post.should_receive(:most_recent_published).4 and_return(posts = [mock])5 get :index67 expect(assigns(:posts)).to eq(posts)8 end9 end
  • 46. Action Controller Testability issues1 describe PostsController do2 it assigns @posts do3 Post.should_receive(:most_recent_published).4 and_return(posts = [mock])5 get :index67 expect(assigns(:posts)).to eq(posts)8 end9 end
  • 47. Action ViewActionView
  • 48. Action View Views aren’t views (but templates with logic)Without “real” views (or In an ideal world wepresenters), we’re tempted to shouldn’t test ourpush presentational methods templates.into the models.
  • 49. Action View Helpers are functional programming1 def user_full_name(user)2 [ user.first_name, user.last_name ].join( )3 end45 url_for6 # vs Half-assed way to solve7 Url.for presentational problems in8 ActionView.9 posts_url
  • 50. Action View Helpers are functional programming1 def user_full_name(user)2 [ user.first_name, user.last_name ].join( )3 end45 url_for6 # vs Half-assed way to solve7 Url.for presentational problems in8 ActionView.9 posts_url
  • 51. Ruby on RailsRuby on Rails
  • 52. Ruby on RailsRails isn’t a framework, but an application template
  • 53. Ruby on RailsRails is multi-paradig m as Ruby is.
  • 54. AGENDAintro problems solutions
  • 55. SolutionsDecouple your logic fromActiveRecord as much as possible. AR is focused on data, but OOP is about behavior.
  • 56. Solutions Don’t think inActiveRecord terms. Database is a detail, forget about associations, scopes, validations..
  • 57. SolutionsLet your public API to declare intents. Let your design to emerge via TDD.
  • 58. Solutions Keep methods andaccessors private as much as possible. Public APIs are hard to maintain as the codebase and the team grows.
  • 59. SolutionsSkinny controllers and skinny models. Use ser vice objects or DCI, they are easier and faster to test.
  • 60. SolutionsDon’t be afraid to extract ad-hoc classes forspecific responsibilities. Inner classes are your friends, they help you with details, and aren’t part of your public API.
  • 61. SolutionsUse DIY presenters They will help you to keep your models clean from presentational logic.
  • 62. SolutionsRefactor, refactor, refactor.
  • 63. AGENDAintro problems solutions conclusion
  • 64. Q&A
  • 65. me@lucag uidi.com @jodoshahttps://speakerdeck.com/jodosha/a-rails-criticism Except where otherwise noted, this work is licensed under: http://creativecommons.org/licenses/by-nc-sa/3.0/

×