SlideShare una empresa de Scribd logo
1 de 66
Descargar para leer sin conexión
March 22nd, 2013

A Rails Criticism
how i learned to stop worrying about the Golden Path
                                       Luca Guidi
AGENDA




intro
Luca Guidi
 Senior Developer at Litmus
  @jodosha - http//lucag uidi.com
litmus
Beautiful Email previews
  Campaig n analytics
   Spam filter tests
 HTML code analysis
   And many other..
Why Rails
has revolutionized web
     development?
         (IMHO)
Why Rails
  has revolutionized web
       development?


Convention Over
 Config uration
          (IMHO)

           :)
Why Rails
     has revolutionized web
          development?


Dynamic and innovative
   Convention Over
    Config uration
     ecosystem
             (IMHO)

              :)
Why Rails
     has revolutionized web
          development?


Dynamic and innovative
   Convention Over
   Productivity and
 Developer uration
    Config Happiness
      ecosystem
             (IMHO)
             :)
..but




The Framework is almost
      ten years old
..but




TheLot of Legacy Code
 A Framework is almost
     ten years old
       is around
..but




TheLot of Legacymajor
 A Frameworkais Code
  Upgrades to     almost
 release years old
     ten are *painful*
       is around
AGENDA




intro   problems
Active
 Record



Active
Record
Active
       Record




Models != Records
Active
                     Record




 Encapsulation violations
1 if article.statearticle.published?
        1 unless != 'published'
2   article.update_attribute(state: 'published')
        2   article.publish!
3 end   3 end
       4 # not completely right...
Active
                     Record

 Encapsulation violations
1 if article.statearticle.published?
        1 unless != 'published'
2   article.update_attribute(state: 'published')
        2   article.publish!
3 end   3 end
       4 # not completely right...
Active
                     Record

 Encapsulation violations
1 if article.statearticle.published?
        1 unless != 'published'
2   article.update_attribute(state: 'published')
        2   article.publish!
3 end   3 end
       4 # not completely right...
Active
            Record



  Tell, Don’t Ask
1
2     violations
 article.publish!
 unless article.published?
 # article.publish!
   push the implementation
3 end
  # into the model
4 # not completely right...
Active
              Record
    Tell, Don’t Ask
      violations
1   article.publish!
    unless article.published?
2   # article.publish!
      push the implementation
3   end
    # into the model
4   # not completely right...
Active
              Record
    Tell, Don’t Ask
      violations
1   article.publish!
    unless article.published?
2   # article.publish!
      push the implementation
3   end
    # into the model
4   # not completely right...
Active
                          Record




2
   Implicit vs Explicit API
1 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   end
5    3         limit(5)
6   private
7   scope :published, ->() { where(state: 'published') }
8   scope :recent,    ->(n) { limit(n) }
9 end
Active
                          Record


   Implicit vs Explicit API
1 class Post < ActiveRecord::Base
2    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   end
5    3         limit(5)
6   private
7   scope :published, ->() { where(state: 'published') }
8   scope :recent,    ->(n) { limit(n) }
9 end
Active
                          Record


   Implicit vs Explicit API
1 class Post < ActiveRecord::Base
2    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   end
5    3         limit(5)
6   private
7   scope :published, ->() { where(state: 'published') }
8   scope :recent,    ->(n) { limit(n) }
9 end
Active
                          Record


   Implicit vs Explicit API
1 class Post < ActiveRecord::Base
2    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   end
5    3         limit(5)
6   private
7   scope :published, ->() { where(state: 'published') }
8   scope :recent,    ->(n) { limit(n) }
9 end
Active
      Record




Callbacks abuse
               Non-persistence logic is
               tight to the persistence
               life cycle.

               Eg. Sending emails
Active
       Record




Testability issues
                Micheal Feathers
Active
                Record



A test is not a unit test if it talks
      Testability issues
          to a database.
                          Micheal Feathers
Action
  Controller



 Action
Controller
        It doesn’t affect too much your
        architecture, but it has strange
        OOP design.
Action
                                  Controller


1 class PostsController < ApplicationController
2    before_filter :authenticate


 Frankenstein Controllers
3
4    def new
5    end
6
7    def create
8      @post = Post.new(params[:post])
9
10     if @post.save
11       redirect_to post_url(@post), notice: 'Yay!'
12     else
13       render :new
14     end
15   end
16 end
Action
                                  Controller

 Frankenstein Controllers
1 class PostsController < ApplicationController
2    before_filter :authenticate
3
4    def new
5    end
6
7    def create
8      @post = Post.new(params[:post])
9
10     if @post.save
11       redirect_to post_url(@post), notice: 'Yay!'
12     else
13       render :new
14     end
15   end
16 end
Action
                                  Controller

 Frankenstein Controllers
1 class PostsController < ApplicationController
2    before_filter :authenticate
3
4    def new
5    end
6
7    def create
8      @post = Post.new(params[:post])
9
10     if @post.save
11       redirect_to post_url(@post), notice: 'Yay!'
12     else
13       render :new
14     end
15   end
16 end
Action
                                  Controller

 Frankenstein Controllers
1 class PostsController < ApplicationController
2    before_filter :authenticate
3
4    def new
5    end
6
7    def create
8      @post = Post.new(params[:post])
9
10     if @post.save
11       redirect_to post_url(@post), notice: 'Yay!'
12     else
13       render :new
14     end
15   end
16 end
Action
                                  Controller

 Frankenstein Controllers
1 class PostsController < ApplicationController
2    before_filter :authenticate
3
4    def new
5    end
6
7    def create
8      @post = Post.new(params[:post])
9
10     if @post.save
11       redirect_to post_url(@post), notice: 'Yay!'
12     else
13       render :new
14     end
15   end
16 end
Action
                                  Controller

 Frankenstein Controllers
1 class PostsController < ApplicationController
2    before_filter :authenticate
3
4    def new
5    end
6
7    def create
8      @post = Post.new(params[:post])
9
10     if @post.save
11       redirect_to post_url(@post), notice: 'Yay!'
12     else
13       render :new
14     end
15   end
16 end
Action
                                 Controller


1 class PostsController < ApplicationController
2    # ...


                    Odd classes
3
4    def create
5      @post = Post.new(params[:post])
6
7      if @post.save
8        # ...
9      else
10       # ...
11     end
12   end
13 end
Action
                                 Controller

                    Odd classes
1 class PostsController < ApplicationController
2    # ...
3
4    def create
5      @post = Post.new(params[:post])
6
7      if @post.save
8        # ...
9      else
10       # ...
11     end
12   end
13 end
Action
                                 Controller

                    Odd classes
1 class PostsController < ApplicationController
2    # ...
3
4    def create
5      @post = Post.new(params[:post])
6
7      if @post.save
8        # ...
9      else
10       # ...
11     end
12   end
13 end
Action
                                 Controller

                    Odd classes
1 class PostsController < ApplicationController
2    # ...
3
4    def create
5      @post = Post.new(params[:post])
6
7      if @post.save
8        # ...
9      else
10       # ...
11     end
12   end
13 end
Action
                                  Controller




3
4
 Encapsulation violations
1 class PostsController < ApplicationController
2   # ...

    def create
5     @post = Post.new(params[:post])
6     # ...
7   end
8 end
Action
                                  Controller

 Encapsulation violations
1 class PostsController < ApplicationController
2   # ...
3
4   def create
5     @post = Post.new(params[:post])
6     # ...
7   end
8 end
Action
                        Controller


1 describe PostsController do


         Testability issues
2   it 'assigns @posts' do
3     Post.should_receive(:most_recent_published).
4       and_return(posts = [mock])
5     get :index
6
7     expect(assigns(:posts)).to eq(posts)
8   end
9 end
Action
                        Controller

         Testability issues
1 describe PostsController do
2   it 'assigns @posts' do
3     Post.should_receive(:most_recent_published).
4       and_return(posts = [mock])
5     get :index
6
7     expect(assigns(:posts)).to eq(posts)
8   end
9 end
Action
                        Controller

         Testability issues
1 describe PostsController do
2   it 'assigns @posts' do
3     Post.should_receive(:most_recent_published).
4       and_return(posts = [mock])
5     get :index
6
7     expect(assigns(:posts)).to eq(posts)
8   end
9 end
Action
                        Controller

         Testability issues
1 describe PostsController do
2   it 'assigns @posts' do
3     Post.should_receive(:most_recent_published).
4       and_return(posts = [mock])
5     get :index
6
7     expect(assigns(:posts)).to eq(posts)
8   end
9 end
Action
                        Controller

         Testability issues
1 describe PostsController do
2   it 'assigns @posts' do
3     Post.should_receive(:most_recent_published).
4       and_return(posts = [mock])
5     get :index
6
7     expect(assigns(:posts)).to eq(posts)
8   end
9 end
Action
                        Controller

         Testability issues
1 describe PostsController do
2   it 'assigns @posts' do
3     Post.should_receive(:most_recent_published).
4       and_return(posts = [mock])
5     get :index
6
7     expect(assigns(:posts)).to eq(posts)
8   end
9 end
Action
 View



Action
View
Action
                                View




       Views aren’t views
                     (but templates with logic)

Without “real” views (or                     In an ideal world we
presenters), we’re tempted to                shouldn’t test our
push presentational methods                  templates.
into the models.
Action
                             View



          Helpers are
    functional programming
1   def user_full_name(user)
2     [ user.first_name, user.last_name ].join(' ')
3   end
4
5   url_for
6   # vs                                 Half-assed way to solve
7   Url.for                              presentational problems in
8                                        ActionView.
9   posts_url
Action
                             View
          Helpers are
    functional programming
1   def user_full_name(user)
2     [ user.first_name, user.last_name ].join(' ')
3   end
4
5   url_for
6   # vs                                 Half-assed way to solve
7   Url.for                              presentational problems in
8                                        ActionView.
9   posts_url
Ruby on
  Rails



Ruby on
 Rails
Ruby on
           Rails


Rails isn’t a framework,
  but an application
        template
Ruby on
           Rails



Rails is multi-paradig m
       as Ruby is.
AGENDA




intro   problems   solutions
Solutions



Decouple your logic from
ActiveRecord as much as
        possible.
                      AR is focused on data, but
                      OOP is about behavior.
Solutions




   Don’t think in
ActiveRecord terms.
                   Database is a detail,
                   forget about associations,
                   scopes, validations..
Solutions




Let your public API
 to declare intents.
                   Let your design to emerge
                   via TDD.
Solutions



 Keep methods and
accessors private as
 much as possible.
                    Public APIs are hard to
                    maintain as the codebase
                    and the team grows.
Solutions



Skinny controllers
       and
 skinny models.
             Use ser vice objects or DCI, they
             are easier and faster to test.
Solutions



Don’t be afraid to extract
  ad-hoc classes for
specific responsibilities.
                 Inner classes are your friends,
                 they help you with details, and
                 aren’t part of your public API.
Solutions




Use DIY presenters
            They will help you to keep your
            models clean from presentational
            logic.
Solutions




Refactor, refactor,
    refactor.
AGENDA




intro   problems   solutions   conclusion
Q&A
me@lucag uidi.com
         @jodosha
https://speakerdeck.com/jodosha/a-rails-criticism

               Except where otherwise noted, this work is licensed under:
                   http://creativecommons.org/licenses/by-nc-sa/3.0/
Una Critica a Rails by Luca Guidi

Más contenido relacionado

La actualidad más candente

Java8 tgtbatu javaone
Java8 tgtbatu javaoneJava8 tgtbatu javaone
Java8 tgtbatu javaoneBrian Vermeer
 
The Ring programming language version 1.5.3 book - Part 13 of 184
The Ring programming language version 1.5.3 book - Part 13 of 184The Ring programming language version 1.5.3 book - Part 13 of 184
The Ring programming language version 1.5.3 book - Part 13 of 184Mahmoud Samir Fayed
 
Advanced Jasmine - Front-End JavaScript Unit Testing
Advanced Jasmine - Front-End JavaScript Unit TestingAdvanced Jasmine - Front-End JavaScript Unit Testing
Advanced Jasmine - Front-End JavaScript Unit TestingLars Thorup
 
Intro to Unit Testing in AngularJS
Intro to Unit Testing in AngularJSIntro to Unit Testing in AngularJS
Intro to Unit Testing in AngularJSJim Lynch
 
PgTAP Best Practices
PgTAP Best PracticesPgTAP Best Practices
PgTAP Best PracticesDavid Wheeler
 
Test-Driven Development of AngularJS Applications
Test-Driven Development of AngularJS ApplicationsTest-Driven Development of AngularJS Applications
Test-Driven Development of AngularJS ApplicationsFITC
 
Software engineering ⊇ Software testing
Software engineering ⊇ Software testingSoftware engineering ⊇ Software testing
Software engineering ⊇ Software testingPavel Tcholakov
 
Java(8) The Good, The Bad and the Ugly
Java(8) The Good, The Bad and the UglyJava(8) The Good, The Bad and the Ugly
Java(8) The Good, The Bad and the UglyBrian Vermeer
 
RSpec 3.0: Under the Covers
RSpec 3.0: Under the CoversRSpec 3.0: Under the Covers
RSpec 3.0: Under the CoversBrian Gesiak
 
Javascript Testing with Jasmine 101
Javascript Testing with Jasmine 101Javascript Testing with Jasmine 101
Javascript Testing with Jasmine 101Roy Yu
 
Legacy Code Kata v3.0
Legacy Code Kata v3.0Legacy Code Kata v3.0
Legacy Code Kata v3.0William Munn
 
Legacy Dependency Kata v2.0
Legacy Dependency Kata v2.0Legacy Dependency Kata v2.0
Legacy Dependency Kata v2.0William Munn
 
The Ring programming language version 1.8 book - Part 89 of 202
The Ring programming language version 1.8 book - Part 89 of 202The Ring programming language version 1.8 book - Part 89 of 202
The Ring programming language version 1.8 book - Part 89 of 202Mahmoud Samir Fayed
 
Stop Making Excuses and Start Testing Your JavaScript
Stop Making Excuses and Start Testing Your JavaScriptStop Making Excuses and Start Testing Your JavaScript
Stop Making Excuses and Start Testing Your JavaScriptRyan Anklam
 
Martin Anderson - threads v actors
Martin Anderson - threads v actorsMartin Anderson - threads v actors
Martin Anderson - threads v actorsbloodredsun
 
Angularjs - Unit testing introduction
Angularjs - Unit testing introductionAngularjs - Unit testing introduction
Angularjs - Unit testing introductionNir Kaufman
 
FullStack Reativo com Spring WebFlux + Angular
FullStack Reativo com Spring WebFlux + AngularFullStack Reativo com Spring WebFlux + Angular
FullStack Reativo com Spring WebFlux + AngularLoiane Groner
 

La actualidad más candente (20)

Java8 tgtbatu javaone
Java8 tgtbatu javaoneJava8 tgtbatu javaone
Java8 tgtbatu javaone
 
The Ring programming language version 1.5.3 book - Part 13 of 184
The Ring programming language version 1.5.3 book - Part 13 of 184The Ring programming language version 1.5.3 book - Part 13 of 184
The Ring programming language version 1.5.3 book - Part 13 of 184
 
Advanced Jasmine - Front-End JavaScript Unit Testing
Advanced Jasmine - Front-End JavaScript Unit TestingAdvanced Jasmine - Front-End JavaScript Unit Testing
Advanced Jasmine - Front-End JavaScript Unit Testing
 
Intro to Unit Testing in AngularJS
Intro to Unit Testing in AngularJSIntro to Unit Testing in AngularJS
Intro to Unit Testing in AngularJS
 
PgTAP Best Practices
PgTAP Best PracticesPgTAP Best Practices
PgTAP Best Practices
 
Test-Driven Development of AngularJS Applications
Test-Driven Development of AngularJS ApplicationsTest-Driven Development of AngularJS Applications
Test-Driven Development of AngularJS Applications
 
Software engineering ⊇ Software testing
Software engineering ⊇ Software testingSoftware engineering ⊇ Software testing
Software engineering ⊇ Software testing
 
Java(8) The Good, The Bad and the Ugly
Java(8) The Good, The Bad and the UglyJava(8) The Good, The Bad and the Ugly
Java(8) The Good, The Bad and the Ugly
 
RSpec 3.0: Under the Covers
RSpec 3.0: Under the CoversRSpec 3.0: Under the Covers
RSpec 3.0: Under the Covers
 
Javascript Testing with Jasmine 101
Javascript Testing with Jasmine 101Javascript Testing with Jasmine 101
Javascript Testing with Jasmine 101
 
Legacy Code Kata v3.0
Legacy Code Kata v3.0Legacy Code Kata v3.0
Legacy Code Kata v3.0
 
Legacy Dependency Kata v2.0
Legacy Dependency Kata v2.0Legacy Dependency Kata v2.0
Legacy Dependency Kata v2.0
 
Qunit Java script Un
Qunit Java script UnQunit Java script Un
Qunit Java script Un
 
The Ring programming language version 1.8 book - Part 89 of 202
The Ring programming language version 1.8 book - Part 89 of 202The Ring programming language version 1.8 book - Part 89 of 202
The Ring programming language version 1.8 book - Part 89 of 202
 
Firebase ng2 zurich
Firebase ng2 zurichFirebase ng2 zurich
Firebase ng2 zurich
 
Full Stack Unit Testing
Full Stack Unit TestingFull Stack Unit Testing
Full Stack Unit Testing
 
Stop Making Excuses and Start Testing Your JavaScript
Stop Making Excuses and Start Testing Your JavaScriptStop Making Excuses and Start Testing Your JavaScript
Stop Making Excuses and Start Testing Your JavaScript
 
Martin Anderson - threads v actors
Martin Anderson - threads v actorsMartin Anderson - threads v actors
Martin Anderson - threads v actors
 
Angularjs - Unit testing introduction
Angularjs - Unit testing introductionAngularjs - Unit testing introduction
Angularjs - Unit testing introduction
 
FullStack Reativo com Spring WebFlux + Angular
FullStack Reativo com Spring WebFlux + AngularFullStack Reativo com Spring WebFlux + Angular
FullStack Reativo com Spring WebFlux + Angular
 

Similar a Una Critica a Rails by Luca Guidi

Aprendendo solid com exemplos
Aprendendo solid com exemplosAprendendo solid com exemplos
Aprendendo solid com exemplosvinibaggio
 
Código Saudável => Programador Feliz - Rs on Rails 2010
Código Saudável => Programador Feliz - Rs on Rails 2010Código Saudável => Programador Feliz - Rs on Rails 2010
Código Saudável => Programador Feliz - Rs on Rails 2010Plataformatec
 
Testing Legacy Rails Apps
Testing Legacy Rails AppsTesting Legacy Rails Apps
Testing Legacy Rails AppsRabble .
 
Ruby: OOP, metaprogramming, blocks, iterators, mix-ins, duck typing. Code style
Ruby: OOP, metaprogramming, blocks, iterators, mix-ins, duck typing. Code styleRuby: OOP, metaprogramming, blocks, iterators, mix-ins, duck typing. Code style
Ruby: OOP, metaprogramming, blocks, iterators, mix-ins, duck typing. Code styleAnton Shemerey
 
How To Test Everything
How To Test EverythingHow To Test Everything
How To Test Everythingnoelrap
 
Ruby/Rails
Ruby/RailsRuby/Rails
Ruby/Railsrstankov
 
Checking Clang 11 with PVS-Studio
Checking Clang 11 with PVS-StudioChecking Clang 11 with PVS-Studio
Checking Clang 11 with PVS-StudioAndrey Karpov
 
Rails 3 Beautiful Code
Rails 3 Beautiful CodeRails 3 Beautiful Code
Rails 3 Beautiful CodeGreggPollack
 
GeeCON 2017 - TestContainers. Integration testing without the hassle
GeeCON 2017 - TestContainers. Integration testing without the hassleGeeCON 2017 - TestContainers. Integration testing without the hassle
GeeCON 2017 - TestContainers. Integration testing without the hassleAnton Arhipov
 
JavaScript Cheatsheets with easy way .pdf
JavaScript Cheatsheets with easy way .pdfJavaScript Cheatsheets with easy way .pdf
JavaScript Cheatsheets with easy way .pdfranjanadeore1
 
Aligning Ember.js with Web Standards
Aligning Ember.js with Web StandardsAligning Ember.js with Web Standards
Aligning Ember.js with Web StandardsMatthew Beale
 
Troubleshooting tips from docker support engineers
Troubleshooting tips from docker support engineersTroubleshooting tips from docker support engineers
Troubleshooting tips from docker support engineersDocker, Inc.
 
Fundamental Concepts of React JS for Beginners.pdf
Fundamental Concepts of React JS for Beginners.pdfFundamental Concepts of React JS for Beginners.pdf
Fundamental Concepts of React JS for Beginners.pdfStephieJohn
 

Similar a Una Critica a Rails by Luca Guidi (20)

Aprendendo solid com exemplos
Aprendendo solid com exemplosAprendendo solid com exemplos
Aprendendo solid com exemplos
 
Código Saudável => Programador Feliz - Rs on Rails 2010
Código Saudável => Programador Feliz - Rs on Rails 2010Código Saudável => Programador Feliz - Rs on Rails 2010
Código Saudável => Programador Feliz - Rs on Rails 2010
 
RSpec
RSpecRSpec
RSpec
 
Testing Legacy Rails Apps
Testing Legacy Rails AppsTesting Legacy Rails Apps
Testing Legacy Rails Apps
 
Ruby: OOP, metaprogramming, blocks, iterators, mix-ins, duck typing. Code style
Ruby: OOP, metaprogramming, blocks, iterators, mix-ins, duck typing. Code styleRuby: OOP, metaprogramming, blocks, iterators, mix-ins, duck typing. Code style
Ruby: OOP, metaprogramming, blocks, iterators, mix-ins, duck typing. Code style
 
How To Test Everything
How To Test EverythingHow To Test Everything
How To Test Everything
 
Ruby/Rails
Ruby/RailsRuby/Rails
Ruby/Rails
 
Checking Clang 11 with PVS-Studio
Checking Clang 11 with PVS-StudioChecking Clang 11 with PVS-Studio
Checking Clang 11 with PVS-Studio
 
Java7
Java7Java7
Java7
 
Migrating legacy data
Migrating legacy dataMigrating legacy data
Migrating legacy data
 
Writing Macros
Writing MacrosWriting Macros
Writing Macros
 
Rails 3 Beautiful Code
Rails 3 Beautiful CodeRails 3 Beautiful Code
Rails 3 Beautiful Code
 
Why ruby
Why rubyWhy ruby
Why ruby
 
GeeCON 2017 - TestContainers. Integration testing without the hassle
GeeCON 2017 - TestContainers. Integration testing without the hassleGeeCON 2017 - TestContainers. Integration testing without the hassle
GeeCON 2017 - TestContainers. Integration testing without the hassle
 
JavaScript Cheatsheets with easy way .pdf
JavaScript Cheatsheets with easy way .pdfJavaScript Cheatsheets with easy way .pdf
JavaScript Cheatsheets with easy way .pdf
 
Workshop React.js
Workshop React.jsWorkshop React.js
Workshop React.js
 
Aligning Ember.js with Web Standards
Aligning Ember.js with Web StandardsAligning Ember.js with Web Standards
Aligning Ember.js with Web Standards
 
TDD & BDD
TDD & BDDTDD & BDD
TDD & BDD
 
Troubleshooting tips from docker support engineers
Troubleshooting tips from docker support engineersTroubleshooting tips from docker support engineers
Troubleshooting tips from docker support engineers
 
Fundamental Concepts of React JS for Beginners.pdf
Fundamental Concepts of React JS for Beginners.pdfFundamental Concepts of React JS for Beginners.pdf
Fundamental Concepts of React JS for Beginners.pdf
 

Más de Codemotion

Fuzz-testing: A hacker's approach to making your code more secure | Pascal Ze...
Fuzz-testing: A hacker's approach to making your code more secure | Pascal Ze...Fuzz-testing: A hacker's approach to making your code more secure | Pascal Ze...
Fuzz-testing: A hacker's approach to making your code more secure | Pascal Ze...Codemotion
 
Pompili - From hero to_zero: The FatalNoise neverending story
Pompili - From hero to_zero: The FatalNoise neverending storyPompili - From hero to_zero: The FatalNoise neverending story
Pompili - From hero to_zero: The FatalNoise neverending storyCodemotion
 
Pastore - Commodore 65 - La storia
Pastore - Commodore 65 - La storiaPastore - Commodore 65 - La storia
Pastore - Commodore 65 - La storiaCodemotion
 
Pennisi - Essere Richard Altwasser
Pennisi - Essere Richard AltwasserPennisi - Essere Richard Altwasser
Pennisi - Essere Richard AltwasserCodemotion
 
Michel Schudel - Let's build a blockchain... in 40 minutes! - Codemotion Amst...
Michel Schudel - Let's build a blockchain... in 40 minutes! - Codemotion Amst...Michel Schudel - Let's build a blockchain... in 40 minutes! - Codemotion Amst...
Michel Schudel - Let's build a blockchain... in 40 minutes! - Codemotion Amst...Codemotion
 
Richard Süselbeck - Building your own ride share app - Codemotion Amsterdam 2019
Richard Süselbeck - Building your own ride share app - Codemotion Amsterdam 2019Richard Süselbeck - Building your own ride share app - Codemotion Amsterdam 2019
Richard Süselbeck - Building your own ride share app - Codemotion Amsterdam 2019Codemotion
 
Eward Driehuis - What we learned from 20.000 attacks - Codemotion Amsterdam 2019
Eward Driehuis - What we learned from 20.000 attacks - Codemotion Amsterdam 2019Eward Driehuis - What we learned from 20.000 attacks - Codemotion Amsterdam 2019
Eward Driehuis - What we learned from 20.000 attacks - Codemotion Amsterdam 2019Codemotion
 
Francesco Baldassarri - Deliver Data at Scale - Codemotion Amsterdam 2019 -
Francesco Baldassarri  - Deliver Data at Scale - Codemotion Amsterdam 2019 - Francesco Baldassarri  - Deliver Data at Scale - Codemotion Amsterdam 2019 -
Francesco Baldassarri - Deliver Data at Scale - Codemotion Amsterdam 2019 - Codemotion
 
Martin Förtsch, Thomas Endres - Stereoscopic Style Transfer AI - Codemotion A...
Martin Förtsch, Thomas Endres - Stereoscopic Style Transfer AI - Codemotion A...Martin Förtsch, Thomas Endres - Stereoscopic Style Transfer AI - Codemotion A...
Martin Förtsch, Thomas Endres - Stereoscopic Style Transfer AI - Codemotion A...Codemotion
 
Melanie Rieback, Klaus Kursawe - Blockchain Security: Melting the "Silver Bul...
Melanie Rieback, Klaus Kursawe - Blockchain Security: Melting the "Silver Bul...Melanie Rieback, Klaus Kursawe - Blockchain Security: Melting the "Silver Bul...
Melanie Rieback, Klaus Kursawe - Blockchain Security: Melting the "Silver Bul...Codemotion
 
Angelo van der Sijpt - How well do you know your network stack? - Codemotion ...
Angelo van der Sijpt - How well do you know your network stack? - Codemotion ...Angelo van der Sijpt - How well do you know your network stack? - Codemotion ...
Angelo van der Sijpt - How well do you know your network stack? - Codemotion ...Codemotion
 
Lars Wolff - Performance Testing for DevOps in the Cloud - Codemotion Amsterd...
Lars Wolff - Performance Testing for DevOps in the Cloud - Codemotion Amsterd...Lars Wolff - Performance Testing for DevOps in the Cloud - Codemotion Amsterd...
Lars Wolff - Performance Testing for DevOps in the Cloud - Codemotion Amsterd...Codemotion
 
Sascha Wolter - Conversational AI Demystified - Codemotion Amsterdam 2019
Sascha Wolter - Conversational AI Demystified - Codemotion Amsterdam 2019Sascha Wolter - Conversational AI Demystified - Codemotion Amsterdam 2019
Sascha Wolter - Conversational AI Demystified - Codemotion Amsterdam 2019Codemotion
 
Michele Tonutti - Scaling is caring - Codemotion Amsterdam 2019
Michele Tonutti - Scaling is caring - Codemotion Amsterdam 2019Michele Tonutti - Scaling is caring - Codemotion Amsterdam 2019
Michele Tonutti - Scaling is caring - Codemotion Amsterdam 2019Codemotion
 
Pat Hermens - From 100 to 1,000+ deployments a day - Codemotion Amsterdam 2019
Pat Hermens - From 100 to 1,000+ deployments a day - Codemotion Amsterdam 2019Pat Hermens - From 100 to 1,000+ deployments a day - Codemotion Amsterdam 2019
Pat Hermens - From 100 to 1,000+ deployments a day - Codemotion Amsterdam 2019Codemotion
 
James Birnie - Using Many Worlds of Compute Power with Quantum - Codemotion A...
James Birnie - Using Many Worlds of Compute Power with Quantum - Codemotion A...James Birnie - Using Many Worlds of Compute Power with Quantum - Codemotion A...
James Birnie - Using Many Worlds of Compute Power with Quantum - Codemotion A...Codemotion
 
Don Goodman-Wilson - Chinese food, motor scooters, and open source developmen...
Don Goodman-Wilson - Chinese food, motor scooters, and open source developmen...Don Goodman-Wilson - Chinese food, motor scooters, and open source developmen...
Don Goodman-Wilson - Chinese food, motor scooters, and open source developmen...Codemotion
 
Pieter Omvlee - The story behind Sketch - Codemotion Amsterdam 2019
Pieter Omvlee - The story behind Sketch - Codemotion Amsterdam 2019Pieter Omvlee - The story behind Sketch - Codemotion Amsterdam 2019
Pieter Omvlee - The story behind Sketch - Codemotion Amsterdam 2019Codemotion
 
Dave Farley - Taking Back “Software Engineering” - Codemotion Amsterdam 2019
Dave Farley - Taking Back “Software Engineering” - Codemotion Amsterdam 2019Dave Farley - Taking Back “Software Engineering” - Codemotion Amsterdam 2019
Dave Farley - Taking Back “Software Engineering” - Codemotion Amsterdam 2019Codemotion
 
Joshua Hoffman - Should the CTO be Coding? - Codemotion Amsterdam 2019
Joshua Hoffman - Should the CTO be Coding? - Codemotion Amsterdam 2019Joshua Hoffman - Should the CTO be Coding? - Codemotion Amsterdam 2019
Joshua Hoffman - Should the CTO be Coding? - Codemotion Amsterdam 2019Codemotion
 

Más de Codemotion (20)

Fuzz-testing: A hacker's approach to making your code more secure | Pascal Ze...
Fuzz-testing: A hacker's approach to making your code more secure | Pascal Ze...Fuzz-testing: A hacker's approach to making your code more secure | Pascal Ze...
Fuzz-testing: A hacker's approach to making your code more secure | Pascal Ze...
 
Pompili - From hero to_zero: The FatalNoise neverending story
Pompili - From hero to_zero: The FatalNoise neverending storyPompili - From hero to_zero: The FatalNoise neverending story
Pompili - From hero to_zero: The FatalNoise neverending story
 
Pastore - Commodore 65 - La storia
Pastore - Commodore 65 - La storiaPastore - Commodore 65 - La storia
Pastore - Commodore 65 - La storia
 
Pennisi - Essere Richard Altwasser
Pennisi - Essere Richard AltwasserPennisi - Essere Richard Altwasser
Pennisi - Essere Richard Altwasser
 
Michel Schudel - Let's build a blockchain... in 40 minutes! - Codemotion Amst...
Michel Schudel - Let's build a blockchain... in 40 minutes! - Codemotion Amst...Michel Schudel - Let's build a blockchain... in 40 minutes! - Codemotion Amst...
Michel Schudel - Let's build a blockchain... in 40 minutes! - Codemotion Amst...
 
Richard Süselbeck - Building your own ride share app - Codemotion Amsterdam 2019
Richard Süselbeck - Building your own ride share app - Codemotion Amsterdam 2019Richard Süselbeck - Building your own ride share app - Codemotion Amsterdam 2019
Richard Süselbeck - Building your own ride share app - Codemotion Amsterdam 2019
 
Eward Driehuis - What we learned from 20.000 attacks - Codemotion Amsterdam 2019
Eward Driehuis - What we learned from 20.000 attacks - Codemotion Amsterdam 2019Eward Driehuis - What we learned from 20.000 attacks - Codemotion Amsterdam 2019
Eward Driehuis - What we learned from 20.000 attacks - Codemotion Amsterdam 2019
 
Francesco Baldassarri - Deliver Data at Scale - Codemotion Amsterdam 2019 -
Francesco Baldassarri  - Deliver Data at Scale - Codemotion Amsterdam 2019 - Francesco Baldassarri  - Deliver Data at Scale - Codemotion Amsterdam 2019 -
Francesco Baldassarri - Deliver Data at Scale - Codemotion Amsterdam 2019 -
 
Martin Förtsch, Thomas Endres - Stereoscopic Style Transfer AI - Codemotion A...
Martin Förtsch, Thomas Endres - Stereoscopic Style Transfer AI - Codemotion A...Martin Förtsch, Thomas Endres - Stereoscopic Style Transfer AI - Codemotion A...
Martin Förtsch, Thomas Endres - Stereoscopic Style Transfer AI - Codemotion A...
 
Melanie Rieback, Klaus Kursawe - Blockchain Security: Melting the "Silver Bul...
Melanie Rieback, Klaus Kursawe - Blockchain Security: Melting the "Silver Bul...Melanie Rieback, Klaus Kursawe - Blockchain Security: Melting the "Silver Bul...
Melanie Rieback, Klaus Kursawe - Blockchain Security: Melting the "Silver Bul...
 
Angelo van der Sijpt - How well do you know your network stack? - Codemotion ...
Angelo van der Sijpt - How well do you know your network stack? - Codemotion ...Angelo van der Sijpt - How well do you know your network stack? - Codemotion ...
Angelo van der Sijpt - How well do you know your network stack? - Codemotion ...
 
Lars Wolff - Performance Testing for DevOps in the Cloud - Codemotion Amsterd...
Lars Wolff - Performance Testing for DevOps in the Cloud - Codemotion Amsterd...Lars Wolff - Performance Testing for DevOps in the Cloud - Codemotion Amsterd...
Lars Wolff - Performance Testing for DevOps in the Cloud - Codemotion Amsterd...
 
Sascha Wolter - Conversational AI Demystified - Codemotion Amsterdam 2019
Sascha Wolter - Conversational AI Demystified - Codemotion Amsterdam 2019Sascha Wolter - Conversational AI Demystified - Codemotion Amsterdam 2019
Sascha Wolter - Conversational AI Demystified - Codemotion Amsterdam 2019
 
Michele Tonutti - Scaling is caring - Codemotion Amsterdam 2019
Michele Tonutti - Scaling is caring - Codemotion Amsterdam 2019Michele Tonutti - Scaling is caring - Codemotion Amsterdam 2019
Michele Tonutti - Scaling is caring - Codemotion Amsterdam 2019
 
Pat Hermens - From 100 to 1,000+ deployments a day - Codemotion Amsterdam 2019
Pat Hermens - From 100 to 1,000+ deployments a day - Codemotion Amsterdam 2019Pat Hermens - From 100 to 1,000+ deployments a day - Codemotion Amsterdam 2019
Pat Hermens - From 100 to 1,000+ deployments a day - Codemotion Amsterdam 2019
 
James Birnie - Using Many Worlds of Compute Power with Quantum - Codemotion A...
James Birnie - Using Many Worlds of Compute Power with Quantum - Codemotion A...James Birnie - Using Many Worlds of Compute Power with Quantum - Codemotion A...
James Birnie - Using Many Worlds of Compute Power with Quantum - Codemotion A...
 
Don Goodman-Wilson - Chinese food, motor scooters, and open source developmen...
Don Goodman-Wilson - Chinese food, motor scooters, and open source developmen...Don Goodman-Wilson - Chinese food, motor scooters, and open source developmen...
Don Goodman-Wilson - Chinese food, motor scooters, and open source developmen...
 
Pieter Omvlee - The story behind Sketch - Codemotion Amsterdam 2019
Pieter Omvlee - The story behind Sketch - Codemotion Amsterdam 2019Pieter Omvlee - The story behind Sketch - Codemotion Amsterdam 2019
Pieter Omvlee - The story behind Sketch - Codemotion Amsterdam 2019
 
Dave Farley - Taking Back “Software Engineering” - Codemotion Amsterdam 2019
Dave Farley - Taking Back “Software Engineering” - Codemotion Amsterdam 2019Dave Farley - Taking Back “Software Engineering” - Codemotion Amsterdam 2019
Dave Farley - Taking Back “Software Engineering” - Codemotion Amsterdam 2019
 
Joshua Hoffman - Should the CTO be Coding? - Codemotion Amsterdam 2019
Joshua Hoffman - Should the CTO be Coding? - Codemotion Amsterdam 2019Joshua Hoffman - Should the CTO be Coding? - Codemotion Amsterdam 2019
Joshua Hoffman - Should the CTO be Coding? - Codemotion Amsterdam 2019
 

Último

What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024Stephanie Beckett
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyAlfredo García Lavilla
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr BaganFwdays
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsMark Billinghurst
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubKalema Edgar
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Commit University
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationSlibray Presentation
 
My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024The Digital Insurer
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brandgvaughan
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clashcharlottematthew16
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfRankYa
 
The Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdfThe Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdfSeasiaInfotech2
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Mattias Andersson
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfAddepto
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticscarlostorres15106
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxNavinnSomaal
 

Último (20)

What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easy
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR Systems
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding Club
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck Presentation
 
My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024My INSURER PTE LTD - Insurtech Innovation Award 2024
My INSURER PTE LTD - Insurtech Innovation Award 2024
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
WordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your BrandWordPress Websites for Engineers: Elevate Your Brand
WordPress Websites for Engineers: Elevate Your Brand
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clash
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdf
 
The Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdfThe Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdf
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdf
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
 
DMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special EditionDMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special Edition
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptx
 

Una Critica a Rails by Luca Guidi

  • 1. March 22nd, 2013 A Rails Criticism how i learned to stop worrying about the Golden Path Luca Guidi
  • 3. Luca Guidi Senior Developer at Litmus @jodosha - http//lucag uidi.com
  • 4. litmus Beautiful Email previews Campaig n analytics Spam filter tests HTML code analysis And many other..
  • 5. Why Rails has 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. ..but The Framework is almost ten years old
  • 10. ..but TheLot of Legacy Code A Framework is almost ten years old is around
  • 11. ..but TheLot of Legacymajor A Frameworkais Code Upgrades to almost release years old ten are *painful* is around
  • 12. AGENDA intro problems
  • 14. Active Record Models != Records
  • 15. Active Record Encapsulation violations 1 if article.statearticle.published? 1 unless != 'published' 2 article.update_attribute(state: 'published') 2 article.publish! 3 end 3 end 4 # not completely right...
  • 16. Active Record Encapsulation violations 1 if article.statearticle.published? 1 unless != 'published' 2 article.update_attribute(state: 'published') 2 article.publish! 3 end 3 end 4 # not completely right...
  • 17. Active Record Encapsulation violations 1 if article.statearticle.published? 1 unless != 'published' 2 article.update_attribute(state: 'published') 2 article.publish! 3 end 3 end 4 # not completely right...
  • 18. Active Record Tell, Don’t Ask 1 2 violations article.publish! unless article.published? # article.publish! push the implementation 3 end # into the model 4 # not completely right...
  • 19. Active Record Tell, Don’t Ask violations 1 article.publish! unless article.published? 2 # article.publish! push the implementation 3 end # into the model 4 # not completely right...
  • 20. Active Record Tell, Don’t Ask violations 1 article.publish! unless article.published? 2 # article.publish! push the implementation 3 end # into the model 4 # not completely right...
  • 21. Active Record 2 Implicit vs Explicit API 1 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 end 5 3 limit(5) 6 private 7 scope :published, ->() { where(state: 'published') } 8 scope :recent, ->(n) { limit(n) } 9 end
  • 22. Active Record Implicit vs Explicit API 1 class Post < ActiveRecord::Base 2 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 end 5 3 limit(5) 6 private 7 scope :published, ->() { where(state: 'published') } 8 scope :recent, ->(n) { limit(n) } 9 end
  • 23. Active Record Implicit vs Explicit API 1 class Post < ActiveRecord::Base 2 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 end 5 3 limit(5) 6 private 7 scope :published, ->() { where(state: 'published') } 8 scope :recent, ->(n) { limit(n) } 9 end
  • 24. Active Record Implicit vs Explicit API 1 class Post < ActiveRecord::Base 2 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 end 5 3 limit(5) 6 private 7 scope :published, ->() { where(state: 'published') } 8 scope :recent, ->(n) { limit(n) } 9 end
  • 25. Active Record Callbacks abuse Non-persistence logic is tight to the persistence life cycle. Eg. Sending emails
  • 26. Active Record Testability issues Micheal Feathers
  • 27. Active Record A test is not a unit test if it talks Testability issues to a database. Micheal Feathers
  • 28. Action Controller Action Controller It doesn’t affect too much your architecture, but it has strange OOP design.
  • 29. Action Controller 1 class PostsController < ApplicationController 2 before_filter :authenticate Frankenstein Controllers 3 4 def new 5 end 6 7 def create 8 @post = Post.new(params[:post]) 9 10 if @post.save 11 redirect_to post_url(@post), notice: 'Yay!' 12 else 13 render :new 14 end 15 end 16 end
  • 30. Action Controller Frankenstein Controllers 1 class PostsController < ApplicationController 2 before_filter :authenticate 3 4 def new 5 end 6 7 def create 8 @post = Post.new(params[:post]) 9 10 if @post.save 11 redirect_to post_url(@post), notice: 'Yay!' 12 else 13 render :new 14 end 15 end 16 end
  • 31. Action Controller Frankenstein Controllers 1 class PostsController < ApplicationController 2 before_filter :authenticate 3 4 def new 5 end 6 7 def create 8 @post = Post.new(params[:post]) 9 10 if @post.save 11 redirect_to post_url(@post), notice: 'Yay!' 12 else 13 render :new 14 end 15 end 16 end
  • 32. Action Controller Frankenstein Controllers 1 class PostsController < ApplicationController 2 before_filter :authenticate 3 4 def new 5 end 6 7 def create 8 @post = Post.new(params[:post]) 9 10 if @post.save 11 redirect_to post_url(@post), notice: 'Yay!' 12 else 13 render :new 14 end 15 end 16 end
  • 33. Action Controller Frankenstein Controllers 1 class PostsController < ApplicationController 2 before_filter :authenticate 3 4 def new 5 end 6 7 def create 8 @post = Post.new(params[:post]) 9 10 if @post.save 11 redirect_to post_url(@post), notice: 'Yay!' 12 else 13 render :new 14 end 15 end 16 end
  • 34. Action Controller Frankenstein Controllers 1 class PostsController < ApplicationController 2 before_filter :authenticate 3 4 def new 5 end 6 7 def create 8 @post = Post.new(params[:post]) 9 10 if @post.save 11 redirect_to post_url(@post), notice: 'Yay!' 12 else 13 render :new 14 end 15 end 16 end
  • 35. Action Controller 1 class PostsController < ApplicationController 2 # ... Odd classes 3 4 def create 5 @post = Post.new(params[:post]) 6 7 if @post.save 8 # ... 9 else 10 # ... 11 end 12 end 13 end
  • 36. Action Controller Odd classes 1 class PostsController < ApplicationController 2 # ... 3 4 def create 5 @post = Post.new(params[:post]) 6 7 if @post.save 8 # ... 9 else 10 # ... 11 end 12 end 13 end
  • 37. Action Controller Odd classes 1 class PostsController < ApplicationController 2 # ... 3 4 def create 5 @post = Post.new(params[:post]) 6 7 if @post.save 8 # ... 9 else 10 # ... 11 end 12 end 13 end
  • 38. Action Controller Odd classes 1 class PostsController < ApplicationController 2 # ... 3 4 def create 5 @post = Post.new(params[:post]) 6 7 if @post.save 8 # ... 9 else 10 # ... 11 end 12 end 13 end
  • 39. Action Controller 3 4 Encapsulation violations 1 class PostsController < ApplicationController 2 # ... def create 5 @post = Post.new(params[:post]) 6 # ... 7 end 8 end
  • 40. Action Controller Encapsulation violations 1 class PostsController < ApplicationController 2 # ... 3 4 def create 5 @post = Post.new(params[:post]) 6 # ... 7 end 8 end
  • 41. Action Controller 1 describe PostsController do Testability issues 2 it 'assigns @posts' do 3 Post.should_receive(:most_recent_published). 4 and_return(posts = [mock]) 5 get :index 6 7 expect(assigns(:posts)).to eq(posts) 8 end 9 end
  • 42. Action Controller Testability issues 1 describe PostsController do 2 it 'assigns @posts' do 3 Post.should_receive(:most_recent_published). 4 and_return(posts = [mock]) 5 get :index 6 7 expect(assigns(:posts)).to eq(posts) 8 end 9 end
  • 43. Action Controller Testability issues 1 describe PostsController do 2 it 'assigns @posts' do 3 Post.should_receive(:most_recent_published). 4 and_return(posts = [mock]) 5 get :index 6 7 expect(assigns(:posts)).to eq(posts) 8 end 9 end
  • 44. Action Controller Testability issues 1 describe PostsController do 2 it 'assigns @posts' do 3 Post.should_receive(:most_recent_published). 4 and_return(posts = [mock]) 5 get :index 6 7 expect(assigns(:posts)).to eq(posts) 8 end 9 end
  • 45. Action Controller Testability issues 1 describe PostsController do 2 it 'assigns @posts' do 3 Post.should_receive(:most_recent_published). 4 and_return(posts = [mock]) 5 get :index 6 7 expect(assigns(:posts)).to eq(posts) 8 end 9 end
  • 46. Action Controller Testability issues 1 describe PostsController do 2 it 'assigns @posts' do 3 Post.should_receive(:most_recent_published). 4 and_return(posts = [mock]) 5 get :index 6 7 expect(assigns(:posts)).to eq(posts) 8 end 9 end
  • 48. Action View Views aren’t views (but templates with logic) Without “real” views (or In an ideal world we presenters), we’re tempted to shouldn’t test our push presentational methods templates. into the models.
  • 49. Action View Helpers are functional programming 1 def user_full_name(user) 2 [ user.first_name, user.last_name ].join(' ') 3 end 4 5 url_for 6 # vs Half-assed way to solve 7 Url.for presentational problems in 8 ActionView. 9 posts_url
  • 50. Action View Helpers are functional programming 1 def user_full_name(user) 2 [ user.first_name, user.last_name ].join(' ') 3 end 4 5 url_for 6 # vs Half-assed way to solve 7 Url.for presentational problems in 8 ActionView. 9 posts_url
  • 51. Ruby on Rails Ruby on Rails
  • 52. Ruby on Rails Rails isn’t a framework, but an application template
  • 53. Ruby on Rails Rails is multi-paradig m as Ruby is.
  • 54. AGENDA intro problems solutions
  • 55. Solutions Decouple your logic from ActiveRecord as much as possible. AR is focused on data, but OOP is about behavior.
  • 56. Solutions Don’t think in ActiveRecord terms. Database is a detail, forget about associations, scopes, validations..
  • 57. Solutions Let your public API to declare intents. Let your design to emerge via TDD.
  • 58. Solutions Keep methods and accessors private as much as possible. Public APIs are hard to maintain as the codebase and the team grows.
  • 59. Solutions Skinny controllers and skinny models. Use ser vice objects or DCI, they are easier and faster to test.
  • 60. Solutions Don’t be afraid to extract ad-hoc classes for specific responsibilities. Inner classes are your friends, they help you with details, and aren’t part of your public API.
  • 61. Solutions Use DIY presenters They will help you to keep your models clean from presentational logic.
  • 63. AGENDA intro problems solutions conclusion
  • 64. Q&A
  • 65. me@lucag uidi.com @jodosha https://speakerdeck.com/jodosha/a-rails-criticism Except where otherwise noted, this work is licensed under: http://creativecommons.org/licenses/by-nc-sa/3.0/