Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Solid foundations for Rails apps
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
Mariusz Lusiak
April 22, 2012
Programming
190
4
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Solid foundations for Rails apps
A talk given at Railsberry, the European Rails Conference, on Apr 20, 2012.
Mariusz Lusiak
April 22, 2012
More Decks by Mariusz Lusiak
See All by Mariusz Lusiak
OOP in Rails applications
mariuszlusiak
7
310
Other Decks in Programming
See All in Programming
AI時代のコードレビューは人に向けるな、仕組みに向けろ
texmeijin
5
3.7k
ジョジョの世界をXRで再現する
mofurune
0
160
When benchmarks go bad - what I learned from measuring performance wrong
hollycummins
0
220
[Rails World 2026] Durable orchestration on Rails: from continuation to workflow
palkan
1
750
なぜCTOを降りてFDEを選んだのか?〜なぜプロダクト企業がFDEで顧客の現場に踏み込むのか〜
gonta
1
210
sbt 2.0: takeoff
eed3si9n
0
160
動作中のプログラムの中身をリアルタイムに覗く / Realtime Debugger for CSharp with Roslyn
prota
1
1.9k
dotNET_vulnclicker_intro.pdf
deka_morita
0
140
Atomic Design, Enforced: Scaling Mobile Design Systems (next.app devCon / droidCon Berlin 2026)
steliosf
PRO
0
170
AWSに止められる覚悟してますか?
morizo_1984
2
540
Verilogで学ぶCPU自作入門
uyuki234
8
4.1k
[Dev Group Paris Octobre 26] Agentforce, SIforce, Claudeforce, Slackbot… on s'y retrouve ?
nabondance
0
110
Featured
See All Featured
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
12
1.9k
Highjacked: Video Game Concept Design
rkendrick25
PRO
1
480
How to build a perfect <img>
jonoalderson
1
6.1k
Redefining SEO in the New Era of Traffic Generation
szymonslowik
1
480
Mind Mapping
helmedeiros
1
400
Design of three-dimensional binary manipulators for pick-and-place task avoiding obstacles (IECON2024)
konakalab
0
620
Applied NLP in the Age of Generative AI
inesmontani
PRO
4
2.5k
How to Create Impact in a Changing Tech Landscape [PerfNow 2023]
tammyeverts
56
3.5k
Collaborative Software Design: How to facilitate domain modelling decisions
baasie
1
340
A Guide to Academic Writing Using Generative AI - A Workshop
ks91
PRO
1
520
Discover your Explorer Soul
emna__ayadi
2
1.3k
Exploring the Power of Turbo Streams & Action Cable | RailsConf2023
kevinliebholz
37
6.6k
Transcript
Solid foundations for Rails apps
Love
A sip of frustration
OOP
ISP SRP DRY DI Liskov Open/Closed Least surprise Tell Don’t
Ask Law of Demeter Convention over Configuration Domain Language Capture
ISP SRP DRY DI Liskov Open/Closed Least surprise Tell Don’t
Ask Law of Demeter Convention over Configuration Domain Language Capture
SRP
Change
class User attr_reader :name def bandwidth_usage(month) # Calculate bandwidth usage
end end
class User attr_reader :name end class BandwidthUsage def initialize(user) user
= @user end def by_month(month) # Calculate bandwidth usage end end
Indicators
class Shipment def update_destination(name, address) @first_name, @last_name = name.split(' ')
@address = address end def update_last_name(name) @last_name = name.split(' ').last end end
class Shipment def update_destination(name, address) @first_name, @last_name = extract_names(name) @address
= address end def update_last_name(name) @last_name = extract_names(name).last end private def extract_names(name) name.split(' ') end end
class NameParser def initialize(name) # ... end def first_name #
... end def last_name # ... end end
class Shipment def update_destination(name, address) name_parser = NameParser.new(name) @first_name =
name_parser.first_name @last_name = name_parser.last_name @address = address end def update_last_name(name) name_parser = NameParser.new(name) @last_name = name_parser.last_name end end
Rails vs SRP
Active Record
Data Mapper
Solutions for AR
class User < ActiveRecord::Base include Favourites include Pictures include Organizations
include Embeddable include SocialProfiles # ... end
None
class Post < ActiveRecord::Base include FigLeaf hide ActiveRecord::Base, ancestors: true,
except: [Object, :init_with, :new_record?, :errors, :valid?, :save] hide_singletons ActiveRecord::Calculations, ActiveRecord::FinderMethods, # ...
Yet another reason
Is it easier to add a method to an existing
class or create a new class with that method?
Domain Language Capture
Writers
Coders
Managers, Helpers etc.
All the layers
Communication
None
1 class Tag 2 3 # ... 4 5 end
None
None
1 class Tag 2 3 # ... 4 5 end
Confusion
Unify naming, stay in sync
DRY
Model attributes, Partials, Routes
WET?
None
Knowledge
Comments
# Concatenates the salt with the password salt + password
# Concatenates the salt with the password (password + salt).hash
class User attr_accessor :admin end
user.admin = true
Name the business process
class User attr_accessor :admin def grant_admin_privileges @admin = true end
end
class GrantsAdminPrivileges def initialize(user) @user = user end def execute
@user.admin = true end end
SRP DLC DRY
@mariuszlusiak