Rails traps

  • 2,333 views
Uploaded on

When you're writing a Ruby on Rails application, certain decisions seem appropriate and good at the beginning, but come back to bite you later on. In this talk, I list 20 different "traps," things …

When you're writing a Ruby on Rails application, certain decisions seem appropriate and good at the beginning, but come back to bite you later on. In this talk, I list 20 different "traps," things that seem appealing, but which you should think twice before doing. The talk is based on my experience teaching Ruby and Rails classes to many people over the years, and was a presentation at the "Rails Israel 2012" conference held in Tel Aviv.

More in: Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
2,333
On Slideshare
0
From Embeds
0
Number of Embeds
6

Actions

Shares
Downloads
14
Comments
0
Likes
8

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n

Transcript

  • 1. Rails TrapsReuven M. Lerner • reuven@lerner.co.il International Rails Conference November 12th, 2012 • Tel Aviv
  • 2. Who am I?• Web developer since 1993• Linux Journal columnist since 1996• Long-time developer/trainer/consultant in Ruby, Rails, and PostgreSQL (and many more)
  • 3. What do I do?• Web development, especially in Rails• Teaching/training • 4-day Ruby course in Herzliya next week• Coaching/consulting
  • 4. What is a trap?
  • 5. It looks really good ...
  • 6. ... but it’s not worth the long-term consequences
  • 7. Rails traps• Techniques that look like they’ll benefit us...• ... but which will haunt us down the road• There is some overlap these and “anti- patterns,” a term that people use to describe “design patterns that you should avoid”
  • 8. Trap #1: Always using Rails• Rails is wonderful. Really, it is.• But it’s not the only framework.• (And Ruby isn’t the only language!)• Use Rails because it’s the right framework for the job
  • 9. Alternatives• My favorite: Sinatra• Ridiculously easy to create Web apps, built in Ruby, works with ERb and Haml (and other gems we know and love), and fantastic documentation• But really, you should use what you know, if it gets the job done. (Even PHP...)
  • 10. Trap #2:Ignoring Rails’ opinions• One of the best things about Rails is that it’s opinionated • Files go in specific places • MVC split is (fairly) obvious • ActiveRecord naming is pre-set• If your opinions differ, you may have trouble
  • 11. Don’t be a salmon
  • 12. Opinions may differ... but not in Rails• Yes, you can configure Rails to conform to your opinions• But in doing so, you’re likely to encounter pain — now, and in the future• Different parts of Rails make the same assumptions, so expect extended pain• Stick with the defaults as much as possible
  • 13. Some examples• Always have a synthetic primary key, and always call it “id”• Naming conventions for tables, classes• Fat models and skinny controllers• DRY things up with filters, callbacks
  • 14. Trap #3: Ignoring the logs• Logs are a developer’s best friend• Is there a problem? Check the logs!• Having a problem? Write to the log!• (Check the database log, too!)• Using a debugger should be your last resort, not your first one
  • 15. Trap #4: Ignoring the console• The console (especially with Pry) is one of the most useful parts of Rails• Don’t ignore it, or think that it’s primitive• The console is a critical part of my development and debugging process• It helps me “feel” my way through the app
  • 16. Trap #5: Not being RESTful• For years, Rails has encouraged us to use RESTful resources• You don’t have to; config/routes.rb still contains the following line (in a comment): match :controller(/:action(/:id))(.:format)• Maybe you don’t have to be RESTful. But life is far easier when you accept REST.
  • 17. Being RESTful• Think “resources” rather than controllers• Resources should be nouns, and actions operate on those nouns• Those actions can usually be mapped onto the standard seven methods
  • 18. What REST gives you• Convention over configuration• Ease of maintenance/understanding• Routes, forms, and helpers that just work• Scaffolds (yes, I like scaffolds)• Forces you to think (and rethink) the structure of your application, which an definitely improve it
  • 19. Trap #6: Only being RESTful• REST is a technique, not a religion• If you have non-RESTful controller actions, you are not an evil person! • (Well, not too evil)• Add new member or collection methods when you need them — but not more often than that
  • 20. Trap #7: Self authentication• Rails doesn’t have a built-in authentication system. (This drives me crazy.)• There are gems (e.g., Devise) that do a fantastic job, and which have been used and tested by many sites• Security is hard to get right!• Please don’t roll your own. Use a gem.
  • 21. Trap #8:Premature optimization• Cache everything!• Index everything!• Get huge servers!• Use bit masks in the database to avoid overloading the system!
  • 22. Think about Ruby• Ruby isn’t optimized for program speed, but rather for programmer speed• That is an important competitive advantage• Computers are cheap, but people are not• First make sure your software is maintainable. Then worry whether it’s fast.• And then benchmark before optimizing!
  • 23. Trap #9:DB operations in Ruby• Of course, there are some places where you should consider speed• Databases are really smart and efficient about handling data• Plus, the data is far smaller as tuples than as ActiveRecord objects• Let the database do the serious data lifting
  • 24. Don’t do this• Please don’t do this: Person.all.select {|p| p.age > 40}• This will be incredibly slow.• Serious databases (e.g., PostgreSQL) let you create server-side functions and views, which can manipulate the data before it ever gets to Ruby, at database speeds
  • 25. Trap #10: Different databases• I often see people using SQLite in development, and PostgreSQL in production• Don’t do this, especially if you’re using an open-source database in production• Databases are different — different data types, integrity solutions, and transactional behavior.
  • 26. Trap #11: NoSQL or Bust• I hear many people say that SQL is slow, bad, complex, or otherwise• All of their problems will disappear if they switch to NoSQL!• Really?• That’s like saying, “Hashes are great, so I’ll use them instead of arrays.”
  • 27. Trap #12:The cloud! The cloud!• Cloud solutions are great ...• ... in certain circumstances.• I’m using Heroku with three of my clients right now, and I’m very pleased with their product and support.• But that doesn’t mean it’s a better, or even cheaper, option for everyone out there.
  • 28. My cloudy questions• How much direct control do I want/need over my company’s servers?• Is the cost of cloud services lower than the cost of configuring and maintaining these myself?• How likely am I to have to scale up massively, at a moment’s notice?
  • 29. Trap #13:Long controller actions• It’s so tempting! You want to do so much in your controller action.• But the user doesn’t want to wait for your e-mail to be sent.• Use Resque, Delayed Job, or whatever you want... but put such things in the background, and answer the user ASAP.
  • 30. Trap #14: No DB constraints• Is your Rails application the only program that will ever touch the database?• (Answer: Almost certainly not.)• So why are your constraints only in Rails?• A good database will let you specify not only NOT NULLs, but also valid values to protect your data
  • 31. Trap #15:Lack of callbacks, filters• Callbacks (on ActiveRecord models) and filters (on controller actions) let you separate the “real work” from the less- important work• Keep code short, readable, and DRY
  • 32. Trap #16: Not using “lib”• We talk a lot about MVC in Rails• But don’t forget the “lib” directory• It’s a great place to place modules and classes that are used across your app, or that aren’t specifically tied to MVC• (Remember that lib isn’t automatically in the load path, as of Rails 3.x.)
  • 33. Trap #17: Modifying migrations• Migrations are one of my favorite parts of Rails.• Migrations are reversible: If you make a mistake, you can migrate down, change the migration file, and then migrate up.• Only do this before you have shared your migration with other people
  • 34. Why not?• Once you have pushed your migration, someone might have applied them• Maybe you know to migrate backward, revert the old version, git pull, and then migrate forward... but does everyone?
  • 35. Trap #18: Using class variables• When I teach Ruby, everyone loves class variables! (They also love to call them “static variables.”)• There is a place for class variables, but it’s a very limited one:• Data that needs to be shared across all instances of a class
  • 36. Class variable alternatives• Class-level constants• Class methods• A module with methods or constants• A model (for some types of constants)
  • 37. And don’t forget• Class variables vs. class instance variables• This is where your understanding of the Ruby object model really comes in handy
  • 38. class Confusion @x = 11 # class instance variable @@x = 22 # class variable def initialize @x = 999 # instance variable end def return_x @x # returns 999 end def self.return_x @x # returns 11 end def return_double_x @@x # returns 22 end def self.return_double_x @@x # returns 22 endend
  • 39. class Confusion @x = 11 # class instance variable @@x = 22 # class variable def initialize @x = 999 # instance variable end def return_x @x # returns 999 end def self.return_x @x # returns 11 end def return_double_x @@x # returns 22 end def self.return_double_x @@x # returns 22 endend
  • 40. class Confusion @x = 11 # class instance variable @@x = 22 # class variable def initialize @x = 999 # instance variable end def return_x @x # returns 999 end def self.return_x @x # returns 11 end def return_double_x @@x # returns 22 end def self.return_double_x @@x # returns 22 endend
  • 41. class Confusion @x = 11 # class instance variable @@x = 22 # class variable def initialize @x = 999 # instance variable end def return_x @x # returns 999 end def self.return_x @x # returns 11 end def return_double_x @@x # returns 22 end def self.return_double_x @@x # returns 22 endend
  • 42. class Confusion @x = 11 # class instance variable @@x = 22 # class variable def initialize @x = 999 # instance variable end def return_x @x # returns 999 end def self.return_x @x # returns 11 end def return_double_x @@x # returns 22 end def self.return_double_x @@x # returns 22 endend
  • 43. class Confusion @x = 11 # class instance variable @@x = 22 # class variable def initialize @x = 999 # instance variable end def return_x @x # returns 999 end def self.return_x @x # returns 11 end def return_double_x @@x # returns 22 end def self.return_double_x @@x # returns 22 endend
  • 44. class Confusion @x = 11 # class instance variable @@x = 22 # class variable def initialize @x = 999 # instance variable end def return_x @x # returns 999 end def self.return_x @x # returns 11 end def return_double_x @@x # returns 22 end def self.return_double_x @@x # returns 22 endend
  • 45. Trap #19: Cool technology• Don’t use technology because it’s cool. Use technology because it gets the job done, and helps the business.• So it might be cool to use a pub-sub system written in a .NET port of Clojure that transfers XML using EBCDIC...• ... but is it necessary? Is it the easiest and best solution? Is it maintainable?
  • 46. Choosing technologies• My preference is to use things that are proven, stable, and a little boring• (Like me)• The stability and viability of a project is far more important than the latest cool hack• (Which I’ll install on my own machine to play with, but not use on clients’ projects)
  • 47. Trap #20:Not learning, improving• You cannot survive in our business without learning new techniques all of the time• The Ruby and Rails worlds move especially fast, with new gems released all of the time
  • 48. What to do?• Podcasts (Ruby Rogues, Ruby show, Ruby 5)• Newsletters (Ruby Weekly)• Blogs• Books (remember those?)• Learn other languages! You can pick up a lot of ideas and techniques from them
  • 49. Bonus trap:Not enjoying yourself• Ruby and Rails make programming fun• If you’re not having fun, then maybe you’re not doing it right• (Or go join the wild party that I hear .NET developers are having!)
  • 50. Thanks!(Any questions?) reuven@lerner.co.il http://www.lerner.co.il/ 054-496-8405“reuvenlerner” on Skype/AIM