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

A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024Results
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Servicegiselly40
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Igalia
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...apidays
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024The Digital Insurer
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountPuma Security, LLC
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsJoaquim Jorge
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEarley Information Science
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfEnterprise Knowledge
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUK Journal
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfsudhanshuwaghmare1
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CVKhem
 

Último (20)

A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 

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/