una critica a rails by luca guidi
Post on 12-Sep-2014
1.060 views
DESCRIPTION
Un profondo punto di vista sul perché Ruby on Rails ha rivoluzionato lo sviluppo web. Questo talk focalizzerà la sua attenzione sul “Golden Path” di Rails, sui motivi del suo successo, sui problemi più comuni, e su come le sue API possano essere migliorate. Impareremo a trarre beneficio da uno strumento tanto potente quanto pericoloso, di come mitigare le implicazioni architetturali, di design e testabilità delle vostre applicazioni, migliorando la qualità del codice..TRANSCRIPT
![Page 1: Una Critica a Rails by Luca Guidi](https://reader034.vdocuments.site/reader034/viewer/2022051608/5412c1688d7f720a4e8b46a7/html5/thumbnails/1.jpg)
Luca Guidi
March 22nd, 2013
A Rails Criticismhow i learned to stop worrying about the Golden Path
![Page 2: Una Critica a Rails by Luca Guidi](https://reader034.vdocuments.site/reader034/viewer/2022051608/5412c1688d7f720a4e8b46a7/html5/thumbnails/2.jpg)
AGENDA
intro
![Page 3: Una Critica a Rails by Luca Guidi](https://reader034.vdocuments.site/reader034/viewer/2022051608/5412c1688d7f720a4e8b46a7/html5/thumbnails/3.jpg)
Luca GuidiSenior Developer at Litmus
@jodosha - http//lucaguidi.com
![Page 4: Una Critica a Rails by Luca Guidi](https://reader034.vdocuments.site/reader034/viewer/2022051608/5412c1688d7f720a4e8b46a7/html5/thumbnails/4.jpg)
litmusBeautiful Email previews
Campaign analytics
Spam filter tests
HTML code analysis
And many other..
![Page 5: Una Critica a Rails by Luca Guidi](https://reader034.vdocuments.site/reader034/viewer/2022051608/5412c1688d7f720a4e8b46a7/html5/thumbnails/5.jpg)
Why Railshas revolutionized web
development?(IMHO)
![Page 6: Una Critica a Rails by Luca Guidi](https://reader034.vdocuments.site/reader034/viewer/2022051608/5412c1688d7f720a4e8b46a7/html5/thumbnails/6.jpg)
Why Railshas revolutionized web
development?
(IMHO)
Convention Over Configuration
:)
![Page 7: Una Critica a Rails by Luca Guidi](https://reader034.vdocuments.site/reader034/viewer/2022051608/5412c1688d7f720a4e8b46a7/html5/thumbnails/7.jpg)
Why Railshas revolutionized web
development?
(IMHO)
Convention Over Configuration
Dynamic and innovativeecosystem
:)
![Page 8: Una Critica a Rails by Luca Guidi](https://reader034.vdocuments.site/reader034/viewer/2022051608/5412c1688d7f720a4e8b46a7/html5/thumbnails/8.jpg)
Why Railshas revolutionized web
development?
(IMHO)
Convention Over Configuration
Dynamic and innovativeecosystem
Productivity andDeveloper Happiness
:)
![Page 9: Una Critica a Rails by Luca Guidi](https://reader034.vdocuments.site/reader034/viewer/2022051608/5412c1688d7f720a4e8b46a7/html5/thumbnails/9.jpg)
..but
The Framework is almost ten years old
![Page 10: Una Critica a Rails by Luca Guidi](https://reader034.vdocuments.site/reader034/viewer/2022051608/5412c1688d7f720a4e8b46a7/html5/thumbnails/10.jpg)
..but
The Framework is almost ten years old
A Lot of Legacy Codeis around
![Page 11: Una Critica a Rails by Luca Guidi](https://reader034.vdocuments.site/reader034/viewer/2022051608/5412c1688d7f720a4e8b46a7/html5/thumbnails/11.jpg)
..but
The Framework is almost ten years old
A Lot of Legacy Codeis around
Upgrades to a major release are *painful*
![Page 12: Una Critica a Rails by Luca Guidi](https://reader034.vdocuments.site/reader034/viewer/2022051608/5412c1688d7f720a4e8b46a7/html5/thumbnails/12.jpg)
AGENDA
intro problems
![Page 13: Una Critica a Rails by Luca Guidi](https://reader034.vdocuments.site/reader034/viewer/2022051608/5412c1688d7f720a4e8b46a7/html5/thumbnails/13.jpg)
ActiveRecord
Active
Record
![Page 14: Una Critica a Rails by Luca Guidi](https://reader034.vdocuments.site/reader034/viewer/2022051608/5412c1688d7f720a4e8b46a7/html5/thumbnails/14.jpg)
Models != Records
Active
Record
![Page 15: Una Critica a Rails by Luca Guidi](https://reader034.vdocuments.site/reader034/viewer/2022051608/5412c1688d7f720a4e8b46a7/html5/thumbnails/15.jpg)
Encapsulation violations
Active
Record
1 if article.state != 'published'2 article.update_attribute(state: 'published')3 end
1 unless article.published?2 article.publish!3 end4 # not completely right...
![Page 16: Una Critica a Rails by Luca Guidi](https://reader034.vdocuments.site/reader034/viewer/2022051608/5412c1688d7f720a4e8b46a7/html5/thumbnails/16.jpg)
Encapsulation violations
Active
Record
1 if article.state != 'published'2 article.update_attribute(state: 'published')3 end
1 unless article.published?2 article.publish!3 end4 # not completely right...
![Page 17: Una Critica a Rails by Luca Guidi](https://reader034.vdocuments.site/reader034/viewer/2022051608/5412c1688d7f720a4e8b46a7/html5/thumbnails/17.jpg)
Encapsulation violations
Active
Record
1 if article.state != 'published'2 article.update_attribute(state: 'published')3 end
1 unless article.published?2 article.publish!3 end4 # not completely right...
![Page 18: Una Critica a Rails by Luca Guidi](https://reader034.vdocuments.site/reader034/viewer/2022051608/5412c1688d7f720a4e8b46a7/html5/thumbnails/18.jpg)
Tell, Don’t Askviolations
Active
Record
1 unless article.published?2 article.publish!3 end4 # not completely right...
1 article.publish!2 # push the implementation3 # into the model
![Page 19: Una Critica a Rails by Luca Guidi](https://reader034.vdocuments.site/reader034/viewer/2022051608/5412c1688d7f720a4e8b46a7/html5/thumbnails/19.jpg)
Tell, Don’t Askviolations
Active
Record
1 unless article.published?2 article.publish!3 end4 # not completely right...
1 article.publish!2 # push the implementation3 # into the model
![Page 20: Una Critica a Rails by Luca Guidi](https://reader034.vdocuments.site/reader034/viewer/2022051608/5412c1688d7f720a4e8b46a7/html5/thumbnails/20.jpg)
Tell, Don’t Askviolations
Active
Record
1 unless article.published?2 article.publish!3 end4 # not completely right...
1 article.publish!2 # push the implementation3 # into the model
![Page 21: Una Critica a Rails by Luca Guidi](https://reader034.vdocuments.site/reader034/viewer/2022051608/5412c1688d7f720a4e8b46a7/html5/thumbnails/21.jpg)
Implicit vs Explicit API
Active
Record
1 Post.where(state:'published').2 order('created_at DESC').3 limit(5)
1 Post.most_recent_published1 class Post < ActiveRecord::Base2 def self.most_recent_published(limit = 5)3 published.recent(limit).order('created_at DESC')4 end5 6 private7 scope :published, ->() { where(state: 'published') }8 scope :recent, ->(n) { limit(n) }9 end
![Page 22: Una Critica a Rails by Luca Guidi](https://reader034.vdocuments.site/reader034/viewer/2022051608/5412c1688d7f720a4e8b46a7/html5/thumbnails/22.jpg)
Implicit vs Explicit API
Active
Record
1 Post.where(state:'published').2 order('created_at DESC').3 limit(5)
1 Post.most_recent_published1 class Post < ActiveRecord::Base2 def self.most_recent_published(limit = 5)3 published.recent(limit).order('created_at DESC')4 end5 6 private7 scope :published, ->() { where(state: 'published') }8 scope :recent, ->(n) { limit(n) }9 end
![Page 23: Una Critica a Rails by Luca Guidi](https://reader034.vdocuments.site/reader034/viewer/2022051608/5412c1688d7f720a4e8b46a7/html5/thumbnails/23.jpg)
Implicit vs Explicit API
Active
Record
1 Post.where(state:'published').2 order('created_at DESC').3 limit(5)
1 Post.most_recent_published1 class Post < ActiveRecord::Base2 def self.most_recent_published(limit = 5)3 published.recent(limit).order('created_at DESC')4 end5 6 private7 scope :published, ->() { where(state: 'published') }8 scope :recent, ->(n) { limit(n) }9 end
![Page 24: Una Critica a Rails by Luca Guidi](https://reader034.vdocuments.site/reader034/viewer/2022051608/5412c1688d7f720a4e8b46a7/html5/thumbnails/24.jpg)
Implicit vs Explicit API
Active
Record
1 Post.where(state:'published').2 order('created_at DESC').3 limit(5)
1 Post.most_recent_published1 class Post < ActiveRecord::Base2 def self.most_recent_published(limit = 5)3 published.recent(limit).order('created_at DESC')4 end5 6 private7 scope :published, ->() { where(state: 'published') }8 scope :recent, ->(n) { limit(n) }9 end
![Page 25: Una Critica a Rails by Luca Guidi](https://reader034.vdocuments.site/reader034/viewer/2022051608/5412c1688d7f720a4e8b46a7/html5/thumbnails/25.jpg)
Callbacks abuse
Active
Record
Non-persistence logic is tight to the persistence life cycle.
Eg. Sending emails
![Page 26: Una Critica a Rails by Luca Guidi](https://reader034.vdocuments.site/reader034/viewer/2022051608/5412c1688d7f720a4e8b46a7/html5/thumbnails/26.jpg)
Testability issues
Active
Record
Micheal Feathers
![Page 27: Una Critica a Rails by Luca Guidi](https://reader034.vdocuments.site/reader034/viewer/2022051608/5412c1688d7f720a4e8b46a7/html5/thumbnails/27.jpg)
Testability issues
Active
Record
A test is not a unit test if it talks to a database.
Micheal Feathers
![Page 28: Una Critica a Rails by Luca Guidi](https://reader034.vdocuments.site/reader034/viewer/2022051608/5412c1688d7f720a4e8b46a7/html5/thumbnails/28.jpg)
ActionController
Action
Controller
It doesn’t affect too much your architecture, but it has strange OOP design.
![Page 29: Una Critica a Rails by Luca Guidi](https://reader034.vdocuments.site/reader034/viewer/2022051608/5412c1688d7f720a4e8b46a7/html5/thumbnails/29.jpg)
Frankenstein Controllers
Action
Controller
1 class PostsController < ApplicationController2 before_filter :authenticate3 4 def new5 end6 7 def create8 @post = Post.new(params[:post])9 10 if @post.save11 redirect_to post_url(@post), notice: 'Yay!'12 else13 render :new14 end15 end16 end
�!& ��������� !��!��
�!& �����"!��
�!& �����������
����!%���������!�������#����!� ���������"������ �
�%�����"�!�
![Page 30: Una Critica a Rails by Luca Guidi](https://reader034.vdocuments.site/reader034/viewer/2022051608/5412c1688d7f720a4e8b46a7/html5/thumbnails/30.jpg)
Frankenstein ControllersAction
Controller
1 class PostsController < ApplicationController2 before_filter :authenticate3 4 def new5 end6 7 def create8 @post = Post.new(params[:post])9 10 if @post.save11 redirect_to post_url(@post), notice: 'Yay!'12 else13 render :new14 end15 end16 end
�!& ��������� !��!��
�!& �����"!��
�!& �����������
����!%���������!�������#����!� ���������"������ �
�%�����"�!�
![Page 31: Una Critica a Rails by Luca Guidi](https://reader034.vdocuments.site/reader034/viewer/2022051608/5412c1688d7f720a4e8b46a7/html5/thumbnails/31.jpg)
Frankenstein ControllersAction
Controller
1 class PostsController < ApplicationController2 before_filter :authenticate3 4 def new5 end6 7 def create8 @post = Post.new(params[:post])9 10 if @post.save11 redirect_to post_url(@post), notice: 'Yay!'12 else13 render :new14 end15 end16 end
�!& ��������� !��!��
�!& �����"!��
�!& �����������
����!%���������!�������#����!� ���������"������ �
�%�����"�!�
![Page 32: Una Critica a Rails by Luca Guidi](https://reader034.vdocuments.site/reader034/viewer/2022051608/5412c1688d7f720a4e8b46a7/html5/thumbnails/32.jpg)
Frankenstein ControllersAction
Controller
1 class PostsController < ApplicationController2 before_filter :authenticate3 4 def new5 end6 7 def create8 @post = Post.new(params[:post])9 10 if @post.save11 redirect_to post_url(@post), notice: 'Yay!'12 else13 render :new14 end15 end16 end
�!& ��������� !��!��
�!& �����"!��
�!& �����������
����!%���������!�������#����!� ���������"������ �
�%�����"�!�
![Page 33: Una Critica a Rails by Luca Guidi](https://reader034.vdocuments.site/reader034/viewer/2022051608/5412c1688d7f720a4e8b46a7/html5/thumbnails/33.jpg)
Frankenstein ControllersAction
Controller
1 class PostsController < ApplicationController2 before_filter :authenticate3 4 def new5 end6 7 def create8 @post = Post.new(params[:post])9 10 if @post.save11 redirect_to post_url(@post), notice: 'Yay!'12 else13 render :new14 end15 end16 end
�!& ��������� !��!��
�!& �����"!��
�!& �����������
����!%���������!�������#����!� ���������"������ �
�%�����"�!�
![Page 34: Una Critica a Rails by Luca Guidi](https://reader034.vdocuments.site/reader034/viewer/2022051608/5412c1688d7f720a4e8b46a7/html5/thumbnails/34.jpg)
Frankenstein ControllersAction
Controller
1 class PostsController < ApplicationController2 before_filter :authenticate3 4 def new5 end6 7 def create8 @post = Post.new(params[:post])9 10 if @post.save11 redirect_to post_url(@post), notice: 'Yay!'12 else13 render :new14 end15 end16 end
�!& ��������� !��!��
�!& �����"!��
�!& �����������
����!%���������!�������#����!� ���������"������ �
�%�����"�!�
![Page 35: Una Critica a Rails by Luca Guidi](https://reader034.vdocuments.site/reader034/viewer/2022051608/5412c1688d7f720a4e8b46a7/html5/thumbnails/35.jpg)
1 class PostsController < ApplicationController2 # ...34 def create5 @post = Post.new(params[:post])6 7 if @post.save8 # ...9 else10 # ...11 end12 end13 end
Odd classes
Action
Controller
��$�!����������!�� ������!������
��"����&!�����" ��%�"����&!������!�%��� !��!��!�������!���������$�!�������!�!�� ����������%�
![Page 36: Una Critica a Rails by Luca Guidi](https://reader034.vdocuments.site/reader034/viewer/2022051608/5412c1688d7f720a4e8b46a7/html5/thumbnails/36.jpg)
1 class PostsController < ApplicationController2 # ...34 def create5 @post = Post.new(params[:post])6 7 if @post.save8 # ...9 else10 # ...11 end12 end13 end
Odd classesAction
Controller
��$�!����������!�� ������!������
��"����&!�����" ��%�"����&!������!�%��� !��!��!�������!���������$�!�������!�!�� ����������%�
![Page 37: Una Critica a Rails by Luca Guidi](https://reader034.vdocuments.site/reader034/viewer/2022051608/5412c1688d7f720a4e8b46a7/html5/thumbnails/37.jpg)
1 class PostsController < ApplicationController2 # ...34 def create5 @post = Post.new(params[:post])6 7 if @post.save8 # ...9 else10 # ...11 end12 end13 end
Odd classesAction
Controller
��$�!����������!�� ������!������
��"����&!�����" ��%�"����&!������!�%��� !��!��!�������!���������$�!�������!�!�� ����������%�
![Page 38: Una Critica a Rails by Luca Guidi](https://reader034.vdocuments.site/reader034/viewer/2022051608/5412c1688d7f720a4e8b46a7/html5/thumbnails/38.jpg)
1 class PostsController < ApplicationController2 # ...34 def create5 @post = Post.new(params[:post])6 7 if @post.save8 # ...9 else10 # ...11 end12 end13 end
Odd classesAction
Controller
��$�!����������!�� ������!������
��"����&!�����" ��%�"����&!������!�%��� !��!��!�������!���������$�!�������!�!�� ����������%�
![Page 39: Una Critica a Rails by Luca Guidi](https://reader034.vdocuments.site/reader034/viewer/2022051608/5412c1688d7f720a4e8b46a7/html5/thumbnails/39.jpg)
1 class PostsController < ApplicationController2 # ...34 def create5 @post = Post.new(params[:post])6 # ...7 end8 end
Encapsulation violations
Action
Controller
��$�!����������!�� ������!��������� ��#���$��������������!��!� ! �����#��$ ��
![Page 40: Una Critica a Rails by Luca Guidi](https://reader034.vdocuments.site/reader034/viewer/2022051608/5412c1688d7f720a4e8b46a7/html5/thumbnails/40.jpg)
1 class PostsController < ApplicationController2 # ...34 def create5 @post = Post.new(params[:post])6 # ...7 end8 end
Encapsulation violationsAction
Controller
��$�!����������!�� ������!��������� ��#���$��������������!��!� ! �����#��$ ��
![Page 41: Una Critica a Rails by Luca Guidi](https://reader034.vdocuments.site/reader034/viewer/2022051608/5412c1688d7f720a4e8b46a7/html5/thumbnails/41.jpg)
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
Testability issues
Action
Controller
��� �� ������!����!����!� ! �����&!������!�!�� ����������%� ��$������������� !"�����!����!��
��!������������!�!���
��� �� �����������!��!�' !��� (!��� !�!�������!������!�������
![Page 42: Una Critica a Rails by Luca Guidi](https://reader034.vdocuments.site/reader034/viewer/2022051608/5412c1688d7f720a4e8b46a7/html5/thumbnails/42.jpg)
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
Testability issuesAction
Controller
��� �� ������!����!����!� ! �����&!������!�!�� ����������%� ��$������������� !"�����!����!��
��!������������!�!���
��� �� �����������!��!�' !��� (!��� !�!�������!������!�������
![Page 43: Una Critica a Rails by Luca Guidi](https://reader034.vdocuments.site/reader034/viewer/2022051608/5412c1688d7f720a4e8b46a7/html5/thumbnails/43.jpg)
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
Testability issuesAction
Controller
��� �� ������!����!����!� ! �����&!������!�!�� ����������%� ��$������������� !"�����!����!��
��!������������!�!���
��� �� �����������!��!�' !��� (!��� !�!�������!������!�������
![Page 44: Una Critica a Rails by Luca Guidi](https://reader034.vdocuments.site/reader034/viewer/2022051608/5412c1688d7f720a4e8b46a7/html5/thumbnails/44.jpg)
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
Testability issuesAction
Controller
��� �� ������!����!����!� ! �����&!������!�!�� ����������%� ��$������������� !"�����!����!��
��!������������!�!���
��� �� �����������!��!�' !��� (!��� !�!�������!������!�������
![Page 45: Una Critica a Rails by Luca Guidi](https://reader034.vdocuments.site/reader034/viewer/2022051608/5412c1688d7f720a4e8b46a7/html5/thumbnails/45.jpg)
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
Testability issuesAction
Controller
��� �� ������!����!����!� ! �����&!������!�!�� ����������%� ��$������������� !"�����!����!��
��!������������!�!���
��� �� �����������!��!�' !��� (!��� !�!�������!������!�������
![Page 46: Una Critica a Rails by Luca Guidi](https://reader034.vdocuments.site/reader034/viewer/2022051608/5412c1688d7f720a4e8b46a7/html5/thumbnails/46.jpg)
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
Testability issuesAction
Controller
��� �� ������!����!����!� ! �����&!������!�!�� ����������%� ��$������������� !"�����!����!��
��!������������!�!���
��� �� �����������!��!�' !��� (!��� !�!�������!������!�������
![Page 47: Una Critica a Rails by Luca Guidi](https://reader034.vdocuments.site/reader034/viewer/2022051608/5412c1688d7f720a4e8b46a7/html5/thumbnails/47.jpg)
ActionView
Action
View
![Page 48: Una Critica a Rails by Luca Guidi](https://reader034.vdocuments.site/reader034/viewer/2022051608/5412c1688d7f720a4e8b46a7/html5/thumbnails/48.jpg)
Views aren’t views
Action
View
(but templates with logic)
Without “real” views (or presenters), we’re tempted to push presentational methods into the models.
In an ideal world we shouldn’t test our templates.
![Page 49: Una Critica a Rails by Luca Guidi](https://reader034.vdocuments.site/reader034/viewer/2022051608/5412c1688d7f720a4e8b46a7/html5/thumbnails/49.jpg)
Helpers arefunctional programming
Action
View
1 def user_full_name(user)2 [ user.first_name, user.last_name ].join(' ')3 end4 5 url_for6 # vs7 Url.for8 9 posts_url
Half-assed way to solvepresentational problems in ActionView.
![Page 50: Una Critica a Rails by Luca Guidi](https://reader034.vdocuments.site/reader034/viewer/2022051608/5412c1688d7f720a4e8b46a7/html5/thumbnails/50.jpg)
Helpers arefunctional programming
Action
View
1 def user_full_name(user)2 [ user.first_name, user.last_name ].join(' ')3 end4 5 url_for6 # vs7 Url.for8 9 posts_url
Half-assed way to solvepresentational problems in ActionView.
![Page 51: Una Critica a Rails by Luca Guidi](https://reader034.vdocuments.site/reader034/viewer/2022051608/5412c1688d7f720a4e8b46a7/html5/thumbnails/51.jpg)
Ruby onRails
Ruby on
Rails
![Page 52: Una Critica a Rails by Luca Guidi](https://reader034.vdocuments.site/reader034/viewer/2022051608/5412c1688d7f720a4e8b46a7/html5/thumbnails/52.jpg)
Rails isn’t a framework,but an application
template
Ruby on
Rails
![Page 53: Una Critica a Rails by Luca Guidi](https://reader034.vdocuments.site/reader034/viewer/2022051608/5412c1688d7f720a4e8b46a7/html5/thumbnails/53.jpg)
Rails is multi-paradigmas Ruby is.
Ruby on
Rails
![Page 54: Una Critica a Rails by Luca Guidi](https://reader034.vdocuments.site/reader034/viewer/2022051608/5412c1688d7f720a4e8b46a7/html5/thumbnails/54.jpg)
AGENDA
intro problems solutions
![Page 55: Una Critica a Rails by Luca Guidi](https://reader034.vdocuments.site/reader034/viewer/2022051608/5412c1688d7f720a4e8b46a7/html5/thumbnails/55.jpg)
Decouple your logic fromActiveRecord as much as
possible.
Solutions
AR is focused on data, but OOP is about behavior.
![Page 56: Una Critica a Rails by Luca Guidi](https://reader034.vdocuments.site/reader034/viewer/2022051608/5412c1688d7f720a4e8b46a7/html5/thumbnails/56.jpg)
Don’t think in ActiveRecord terms.
Solutions
Database is a detail, forget about associations,scopes, validations..
![Page 57: Una Critica a Rails by Luca Guidi](https://reader034.vdocuments.site/reader034/viewer/2022051608/5412c1688d7f720a4e8b46a7/html5/thumbnails/57.jpg)
Let your public APIto declare intents.
Solutions
Let your design to emerge via TDD.
![Page 58: Una Critica a Rails by Luca Guidi](https://reader034.vdocuments.site/reader034/viewer/2022051608/5412c1688d7f720a4e8b46a7/html5/thumbnails/58.jpg)
Keep methods and accessors private as
much as possible.
Solutions
Public APIs are hard to maintain as the codebase and the team grows.
![Page 59: Una Critica a Rails by Luca Guidi](https://reader034.vdocuments.site/reader034/viewer/2022051608/5412c1688d7f720a4e8b46a7/html5/thumbnails/59.jpg)
Skinny controllersand
skinny models.
Solutions
Use service objects or DCI, they are easier and faster to test.
![Page 60: Una Critica a Rails by Luca Guidi](https://reader034.vdocuments.site/reader034/viewer/2022051608/5412c1688d7f720a4e8b46a7/html5/thumbnails/60.jpg)
Don’t be afraid to extract ad-hoc classes for
specific responsibilities.
Solutions
Inner classes are your friends, they help you with details, and aren’t part of your public API.
![Page 61: Una Critica a Rails by Luca Guidi](https://reader034.vdocuments.site/reader034/viewer/2022051608/5412c1688d7f720a4e8b46a7/html5/thumbnails/61.jpg)
Use DIY presenters
Solutions
They will help you to keep your models clean from presentational logic.
![Page 62: Una Critica a Rails by Luca Guidi](https://reader034.vdocuments.site/reader034/viewer/2022051608/5412c1688d7f720a4e8b46a7/html5/thumbnails/62.jpg)
Refactor, refactor, refactor.
Solutions
![Page 63: Una Critica a Rails by Luca Guidi](https://reader034.vdocuments.site/reader034/viewer/2022051608/5412c1688d7f720a4e8b46a7/html5/thumbnails/63.jpg)
AGENDA
intro problems solutions conclusion
![Page 64: Una Critica a Rails by Luca Guidi](https://reader034.vdocuments.site/reader034/viewer/2022051608/5412c1688d7f720a4e8b46a7/html5/thumbnails/64.jpg)
Q&A
![Page 65: Una Critica a Rails by Luca Guidi](https://reader034.vdocuments.site/reader034/viewer/2022051608/5412c1688d7f720a4e8b46a7/html5/thumbnails/65.jpg)
[email protected]@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/
![Page 66: Una Critica a Rails by Luca Guidi](https://reader034.vdocuments.site/reader034/viewer/2022051608/5412c1688d7f720a4e8b46a7/html5/thumbnails/66.jpg)
��������