This is a collection of small tips and tricks related to developing web applications using the Ruby on Rails framework.
These tips are gathered from my personal experience of 4 years working with the framework, including more than 2 years of professional work at Belighted.
The talk was given in the Ruby on Rails Developer Room at Fosdem 2010 (www.fosdem.org).
4. a x
nt
sy
1. CROSS THE CHANNEL
• Only code in english
• Pay attention to the speling, but also to the meaning
• IT = information technology
5. x
2. AVOID AWKWARD
a
nt
sy
SILENCES
• Forbid trailing whitespaces
• Forbid useless empty lines
• Forbid space/tabs mixes
• Why:
• There are people who care
• Nobody likes useless/noisy diff files
6. 3. {{SOME STUPID WORD
ch
ar
PLAY ON REST}}
• Use REST everywhere, by default
• Only difficult in some cases
• Links from email (always GET)
• Interaction without other tools (payment gateways, etc.)
7. ch
ar
4. ORGANIZE YOUR APP
• Don’t be afraid to enhance the Rails
directory structure
• Tellrails about it in
config/environment.rb
8. ch
ar
5. KICK RJS OUT
• RJS = Javascript written in Ruby and sent asynchronously
• XMLHttpRequest (XHR) is for sending data asynchronously
• Keep the behaviour in your behaviour (JS) files
9. 6. CONSIDER PRESENTERS
ch
ar
AND CONDUCTORS
• Presenter
• layer between the controller and the view
• holds all the presentation stuff related to your model
(formatted currency/dates, etc.)
• Conductor
• layer between the model and the controller
• handles multi-model forms
10. ls
7. UNDERSTAND MODEL
e
od
m
HOOKS
• before_validation: forprocessing user-submitted data before
validating it (ex.: lowercase domain name etc.)
• before_save: for
saving computed stuff in the model (like
timestamps, hashes, ...)
• after_save: for updating related models
• Never call save/update in a hook!
11. els
od
m
8. ORGANIZE YOUR MODELS
• Keep consistent in the way you code your models
• I’m used to this order:
• behavior-related stuff (usually from plugins like acts_as_...)
• relationships (belongs_to/has_many) and named_scopes
• validations
• hooks
• attributes-related stuff
• methods grouped by aspect (authentication, messaging, ...)
12. els
od
m
9. OBSERVE BY ASPECT
• Observers can manage multiple models
• Make one observer per purpose, for example
• notification observer
• mail observer
• referral observer
13. s
10. DON’T CALL THE DB
w
vie
FROM YOUR VIEWS
• MVC : no call to the model layer from views
• All dynamic data should be defined in controller variables
@users_count vs. @users.count
• Why:
• Separation of concerns / loose coupling
• Unit testing
14. s
w
vie
11. CONSIDER HAML/SASS
• More concise than vanilla
HTML/CSS
• Prevents you from invalid
markup
• HTML5-compatible
15. s
er
lp
he
12. HELP YOUR VIEWS
• Use helpers for
• repeated chunks of view code (will DRY your views)
• presentation
logic like first_tab_is_active? (will make your
code more readable)
• You can also use helper_method if you need the logic in
controllers as well
16. s
er
13. USE THE BEST
lp
he
LANGUAGE FOR EACH TASK
• Generate HTML in HTML (or Haml ;-))
• Avoid content_tags in helpers, rather call partials
• Easier for html slicers to understand
17. s
er
lp
he
14. HELP BY ASPECT
• Rails generate by default one helper per controller
• Erase them all and use aspect-oriented helpers
• links_helper
• menu_helper
• avatar_helper
18. s
er
lp
he
15. USE CLEVER LINK HELPERS
• You often have presentation logic which depends on the
context
• Example: a link to a profile page in a social network
• is it you ? / one of your friends ? / someone else ?
• create link_to_user which will point to the good controller
19. rs
lle
16. MINIMIZE INTERACTIONS
ro
nt
co
BETWEEN C AND M
• Only call a model once in each controller method (besides
save/update)
• Why:
• Separation of concerns (prevents inconsistency if several
controllers deal with the same models)
• Keep all the logic related to the model in one place
20. rs
lle
ro
nt
co
17. SKINNY C, FAT M
• Put all business logic in your model
• The role of the controller layer is to
• get user input and send it to the model layer
• send the answer back to the user
21. rs
lle
18. KEEP CONSISTENT
ro
nt
co
CONTROLLERS
• Try to keep the same order in your REST methods
• I’mused to INCSEUD (typical workflow)
index / new / create / show / edit / update / destroy
22. e
as
19. AVOID DATA IN
abt
da
MIGRATIONS
• There’s a rake db:seed task for your “kickstart” data
• For demo/dev data, create your own rake tasks
• Exception: refactoring-related migrations sometimes need data
23. e
as
20. PAY ATTENTION TO
abt
da
RDBMS DATATYPES
• Length of fields
• Varchar vs. char vs. text
• Integer rather than float for currency
24. y
rit
21. XSS-PROTECT
cu
se
YOUR TEXT FIELDS
• XSS = cross-site scripting
• Protect all your text fields which are manipulated by the user
• xss_terminate plugin
• Don’t protect serialized fields
25. y
rit
22. PROTECT YOUR FIELDS
cu
se
FROM MASS-ASSIGNMENT
• @user.update_attributes(params[:user]) # { :admin => true }
• Users can forge form submission (with cURL, etc.)
• Put an empty attr_accessible clause in each model upon
creation, and add “safe” fields one by one
26. y
rit
cu
se
23. SCOPE BY DEFAULT
• In your controllers, scope every request to the current user
• current_user.messages.find(params[:id])
• current_user.messages.build(params[:message])
• Even in methods where it’s not necessary (like new), for
consistency
27. y
plo
24. DEPLOY WITH GREAT
de
TOOLS
• What works well for us (for the moment!):
• Ruby Enterprise Edition + nginx + Capistrano + GitHub
• Heroku
28. isc
m
25. USE RUBY
• In case you didn’t know, Rails is based on it.
• Embrace functional programming
thing.select {|t| t.valid?}.map {|t| t.stuff}.flatten.uniq
• Don’t be afraid of meta-programming, it can help you!
• Create domain-specific languages for your app
• Generate groups of similar methods at once