SlideShare a Scribd company logo
The Renegade’s Guide
  to Hacking Rails
      Internals
      Pradeep Elankumaran
         Michael Bleigh
         Intridea, Inc.
Renegades Guide to Hacking Rails Internals
vendor/rails
   (or edge rails)
why hack the
 internals?
you’ll learn a lot
know your tools
you may have to
you can do some
 very cool stuff
asynchronous
  goodness
keeps your app
     DRY
keeps multiple
  apps DRY
effective ownage
hack when you
   need to
internals are
 dangerous
cover your ass
  with tests.
enough talk.
 code time
Part 1
Initialization
initializer recap
Rails::Initializer
Rails::Configuration
Rails::Initializer#process
require ‘config/environment.rb’
Part 2
The Class Loader
ActiveSupport::Dependencies
require v. load
const_missing( )
has_many :users

  :users => User (not loaded yet)

  ActiveSupport::Dependencies.load_missing_constant(:User)


    (searches through Dependencies.load_paths)

  (finds the first file that matches => app/models/user.rb)

             require_or_load(‘app/models/user.rb’)
let’s talk about
     plugins.
app-slice plugins?
there are a few options
         engines
          desert
        tiny_apps
what ours is gonna do
 • controllers, models and views
 • routes
 • all easily overridden by RAILS_ROOT/app
plugins recap
Rails::Plugin
Rails::Plugin::Loader
Rails::Plugin::Locator
Dependencies#const_missing
break
first lesson: don’t book
 flight to arrive 1.5 hrs
   before conference
I don’t understand a
lot of Rails internals
approach it
practically
find an
entry point
trial and error,
   and error,
   and error.
Part 3
Rails Routing
case study:
subdomain-fu
SubdomainFu To-Do

1) add subdomain to helpers
2) add condition to routes
3) profit
Route Helpers
the entry point:
CODE SPELUNKING
start with
familiar turf:
   url_for
selective
be the spider
       ^
know when
  to quit
code time.
Route Conditions
the entry point:
 JAMIS BUCK
extra credit:
EXISTING PLUGIN
great coders
   steal.
code time.
for more route
    goodness:
weblog.jamisbuck.org
Part 4
ActionView
case study:
  uberkit
What’s In The Kit


1) site navigation generator
2) DRYer forms
built to be
built upon
Helpers on
 Steroids
the entry point:
   form_for
ActionView::Helpers::
CaptureHelper
The Goal
menu ‘nav’ do |m|
  m.action 'Home', home_path
  m.action 'My Profile', user_path(user)
end

          Becomes (when at /home)

<ul id='nav'>
  <li class='current'><a href='/home'>Home</a></li>
  <li><a href='/users/mbleigh'>My Profile</a></li>
</ul>
collect and build
for max control.
code time.
Form Builders
FormBuilder puts the
  f in f.text_field
the entry point:
EXISTING PLUGIN
code time.
wrapping up
rails is just ruby.
know your advanced ruby




        (great book, not affiliated)
never replace the
   rails code
    directly
take it slow
test a lot




[seattle.rb at
RailsConf 2008]
keep your code
  beautiful
   concise
    clear

More Related Content

PDF
More than a side salad: behaviour driven testing and test driven design in Dj...
PPT
Redmine Betabeers SVQ
PDF
Feature Detection for UI Testing
PPT
Joomla Request To Response
PDF
Avoiding Common Pitfalls in Ember.js
PDF
Web services with laravel
PDF
Enemy of the state
PDF
20150319 testotipsio
More than a side salad: behaviour driven testing and test driven design in Dj...
Redmine Betabeers SVQ
Feature Detection for UI Testing
Joomla Request To Response
Avoiding Common Pitfalls in Ember.js
Web services with laravel
Enemy of the state
20150319 testotipsio

Similar to Renegades Guide to Hacking Rails Internals (20)

PDF
Agile Web Development With Rails Third Edition Third Ruby Sam
PDF
Survey of Front End Topics in Rails
PPTX
Learning Web Development with Ruby on Rails Launch
PPT
Rails 3
PDF
Rupicon 2014 Action pack
PDF
Curso rails
PDF
RubyOnRails-Cheatsheet-BlaineKendall
PDF
RubyOnRails-Cheatsheet-BlaineKendall
KEY
MonoRails - GoGaRuCo 2012
PDF
Lightening a component based Rails architecture
PPT
Ruby On Rails Siddhesh
KEY
25 Real Life Tips In Ruby on Rails Development
PDF
How to disassemble one monster app into an ecosystem of 30
KEY
Keeping Rails on the Tracks
PDF
Ruby Rails Web Development.pdf
PPT
Rails
 
PDF
Ruby on Rails 101 - Presentation Slides for a Five Day Introductory Course
PDF
Pragmatic Agile Web Development With Rails.3rd Edition.2009
 
PDF
Ruby on-rails-101-presentation-slides-for-a-five-day-introductory-course-1194...
PPTX
12 Introduction to Rails
Agile Web Development With Rails Third Edition Third Ruby Sam
Survey of Front End Topics in Rails
Learning Web Development with Ruby on Rails Launch
Rails 3
Rupicon 2014 Action pack
Curso rails
RubyOnRails-Cheatsheet-BlaineKendall
RubyOnRails-Cheatsheet-BlaineKendall
MonoRails - GoGaRuCo 2012
Lightening a component based Rails architecture
Ruby On Rails Siddhesh
25 Real Life Tips In Ruby on Rails Development
How to disassemble one monster app into an ecosystem of 30
Keeping Rails on the Tracks
Ruby Rails Web Development.pdf
Rails
 
Ruby on Rails 101 - Presentation Slides for a Five Day Introductory Course
Pragmatic Agile Web Development With Rails.3rd Edition.2009
 
Ruby on-rails-101-presentation-slides-for-a-five-day-introductory-course-1194...
12 Introduction to Rails

Recently uploaded (20)

PDF
Chapter 3 Spatial Domain Image Processing.pdf
PDF
Empathic Computing: Creating Shared Understanding
PDF
Machine learning based COVID-19 study performance prediction
PPTX
Big Data Technologies - Introduction.pptx
DOCX
The AUB Centre for AI in Media Proposal.docx
PPTX
ACSFv1EN-58255 AWS Academy Cloud Security Foundations.pptx
PPT
Teaching material agriculture food technology
PPTX
Spectroscopy.pptx food analysis technology
PDF
cuic standard and advanced reporting.pdf
PDF
MIND Revenue Release Quarter 2 2025 Press Release
PPTX
Machine Learning_overview_presentation.pptx
PPTX
MYSQL Presentation for SQL database connectivity
PDF
NewMind AI Weekly Chronicles - August'25-Week II
PDF
gpt5_lecture_notes_comprehensive_20250812015547.pdf
PDF
Network Security Unit 5.pdf for BCA BBA.
PPTX
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
PDF
Assigned Numbers - 2025 - Bluetooth® Document
PPTX
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
PDF
Encapsulation_ Review paper, used for researhc scholars
PPTX
Cloud computing and distributed systems.
Chapter 3 Spatial Domain Image Processing.pdf
Empathic Computing: Creating Shared Understanding
Machine learning based COVID-19 study performance prediction
Big Data Technologies - Introduction.pptx
The AUB Centre for AI in Media Proposal.docx
ACSFv1EN-58255 AWS Academy Cloud Security Foundations.pptx
Teaching material agriculture food technology
Spectroscopy.pptx food analysis technology
cuic standard and advanced reporting.pdf
MIND Revenue Release Quarter 2 2025 Press Release
Machine Learning_overview_presentation.pptx
MYSQL Presentation for SQL database connectivity
NewMind AI Weekly Chronicles - August'25-Week II
gpt5_lecture_notes_comprehensive_20250812015547.pdf
Network Security Unit 5.pdf for BCA BBA.
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
Assigned Numbers - 2025 - Bluetooth® Document
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
Encapsulation_ Review paper, used for researhc scholars
Cloud computing and distributed systems.

Renegades Guide to Hacking Rails Internals

Editor's Notes

  • #2: good morning guys!\nthis is the renegade&amp;#x2019;s guide to hacking rails internals\n(introduce ourselves)\n
  • #3: we&amp;#x2019;re from Intridea\nproducts &amp; services\nscalr, crowdsound, mediaplug &amp; socialspring\n
  • #4: how many of you have opened up vendor/rails to take a look inside?\nhow many have written a plugin?\nhow many have written something in lib/ that has overridden rails internals?\n
  • #5: so why would you even want to hack the internals? there are quite a few compelling reasons...\n
  • #6: you will learn a lot.\nthe rails internals are a veritable treasure trove of excellent Ruby code. you learn the internals and you will pretty much learn all the ins and outs of Ruby syntax and the way different pieces fit together within the language\n
  • #7: rails is a tool built on ruby. if you use it everyday, it only makes sense to know its limits and the way it&amp;#x2019;s put together.\n
  • #8: you will always run into instances where \n
  • #9: learning the internals lets you do lots of cool stuff -- it&amp;#x2019;s an investment\n
  • #10: we can offload stuff to queues (example starling)\nwe can run separate queue processors independent of the rails app that leverage the code you have written for the app\n\n \n \n\n \n
  • #11: you can really keep things DRY within your codebase by knowing how the Rails class loader works.\n\n \n
  • #12: knowing the internals will let you extract full components of apps into their own separate, shareable rails apps. we will be attemping this soon.\n
  • #13: if you know how the Rails stack operates, you can effectively create ANYTHING using the Rails code you have already written. \nthis is when Rails actually fulfills its promise of being a swiss-army knife. \n\n \n \nkeeping this in mind....\n
  • #14: a few words of advice. you should only hack the internals when you really need to....\n
  • #15: you can screw things up that you didn&amp;#x2019;t even mean to, and that&amp;#x2019;s why you should always...\n
  • #16: rails has quite an extensive test suite. if you&amp;#x2019;re modifying a piece of core code, please make sure you look through the test suite to learn how it&amp;#x2019;s expected to behave. then make sure you write specs or tests to make sure your changes work. then write more tests to make sure your edge cases work. \n
  • #17: first thing we&amp;#x2019;re going to do is to run through how rails actually loads itself.\n
  • #18: \n \n
  • #19: let&amp;#x2019;s do a short recap of the important stuff\n
  • #20: there&amp;#x2019;s a Rails::Initializer class that&amp;#x2019;s used to setup all the necessary classes and initialize Rails.\n
  • #21: you can edit your app&amp;#x2019;s settings by modifying the Rails::Configuration instance that&amp;#x2019;s available in the config/environment.rb file\n
  • #22: the process method contains all the startup steps, in the same order that Rails loads (how convenient!)\n
  • #23: is your best friend. require config/environment.rb in any file and it&amp;#x2019;ll load up the Rails stack for you.\n
  • #24: Now that we know how Rails loads itself, let&amp;#x2019;s see how the Rails class loader operates.\n
  • #25: the rails class loader is completely contained within the ActiveSupport::Dependencies module. it&amp;#x2019;s a really dense piece of code when you first look at it, and it leverages a lot of Ruby magic to get stuff working. \n
  • #26: Rails uses require, which only loads each specified file once in production mode. \nrails uses load() which loads the same file multiple times in development mode.\n
  • #27: the dependencies module uses the const_missing hook to identify classes to load.\nThis is a standard Rails hook method that&amp;#x2019;s called whenever a constant that hasn&amp;#x2019;t been loaded is found. The behavior of the Dependencies module goes a little something like this...\n
  • #28: here&amp;#x2019;s what a typical load trace looks like.\ncode walkthroughs are a little boring -- so let&amp;#x2019;s do a short exercise. \n
  • #29: rails&amp;#x2019; plugin interface is a great way to re-use code across multiple apps. however the default implementation has one big limitation. there are no app-slice plugins. \n
  • #30: these are plugins that have their own controllers, models, helpers, views, routes and migrations. IE -- self-contained &amp;#x201C;apps&amp;#x201D; that can be extracted out into their own quite easily, and also integrated with multiple rails apps with the option of being heavily customized. \n
  • #31: the good thing is that Rails&amp;#x2019; plugin loading code is quite extensible, and slice handling is not impossible to implement. the engines and the desert plugins are a few released plugins that help with this.\nIntridea&amp;#x2019;s SocialSpring social networking platform uses tiny_apps, a custom classloader that allows us to put together custom social networks very, very quickly.\n\n \n \nbut for the sake of learning, let&amp;#x2019;s roll our own.\n
  • #32: so let&amp;#x2019;s code ours up -- first we&amp;#x2019;re going to run through the plugin loader, then we&amp;#x2019;ll code up our own version\n
  • #33: \n \n
  • #34: \n \n
  • #35: \n \n
  • #36: \n \n
  • #37: \n \n
  • #38: let&amp;#x2019;s take a 10 minute break. when we come back, michael&amp;#x2019;s gonna run through hacking actionview and routes!\n
  • #39: \n \n
  • #40: I&amp;#x2019;m going to be presenting with a bit of a different approach. Honestly, I don&amp;#x2019;t understand a lot about Rails internals. To be even more honest, I don&amp;#x2019;t really want to understand everything. I&amp;#x2019;m happy to have a little bit of magic in my life.\n
  • #41: I don&amp;#x2019;t hack internals because I think it&amp;#x2019;s a lark, I do it because I see the potential for real benefit to the projects I&amp;#x2019;m working on. If you don&amp;#x2019;t see yourself saving a lot of time and effort down the road for your efforts in working with internals, you probably shouldn&amp;#x2019;t be doing it.\n
  • #42: The way to manage that initial intimidation factor is to find an entry point, a place that you can get your bearings and go from there. It could be a blog post, an existing plugin, or if you&amp;#x2019;re in uncharted waters, you might just have to read the code yourself.\n
  • #43: When you&amp;#x2019;re monkey-patching, don&amp;#x2019;t expect things to go right the first time. It takes time and patience and a whole hell of a lot of restarting your environment.\n
  • #44: I&amp;#x2019;m going to go over some of the Rails Routing internals both in terms of how it works and where it&amp;#x2019;s easy to extend.\n
  • #45: My knowledge in this area comes from writing the SubdomainFu plugin, which allows Rails apps to easily handle subdomains.\n
  • #46: So I had a couple of goals for SubdomainFu. One, I wanted to be able to use a subdomain option on any of my route helpers and it would &amp;#x201C;just work.&amp;#x201D; Two, I wanted to add a new condition to routes that would allow me to specify things about subdomains in the routing DSL itself.\n
  • #47: So first up, lets tackle the route helpers.\n
  • #48: Unfortunately, I wasn&amp;#x2019;t really able to find a good blog post or existing plugin that worked with adding a universal option to all URL generating methods. I had to do the legwork myself and read through the internals to learn how it worked.\n
  • #49: I started with something that I was familiar with. I knew from various stack traces that url_for was called pretty much every time a route helper was used; this was my entry point.\n
  • #50: Once you have a starting place, you have to begin to understand the area. Act like a Google bot, expanding your knowledge by understanding a method, then understanding the methods that that method calls. If a method&amp;#x2019;s purpose is self-evident and you don&amp;#x2019;t need to modify it for the task at hand, go ahead and skip past that.\n
  • #51: You have to know when to quit. It&amp;#x2019;s a good idea to spelunk for code for a bit until you get a fuzzy general idea of what&amp;#x2019;s going on, then tackle it from a practical perspective and learn the rest while writing code.\n
  • #52: OK, so that&amp;#x2019;s how the general process works when you don&amp;#x2019;t really have an idea of what you&amp;#x2019;re dealing with, let&amp;#x2019;s see some of the fruits of this labor! [LIVECODE TIME]\n
  • #53: So we&amp;#x2019;re done with step one, now it&amp;#x2019;s time to move on to step two! We want to add a new condition to the routes that allows us to specify subdomain-based conditions.\n
  • #54: Here, I was able to get a lot more help from the early settlers. Jamis Buck&amp;#x2019;s blog has a couple of really nice looks at routing internals that gave me a general idea of what I was doing.\n
  • #55: Even better, there was already a subdomain_routing plugin available! The easiest way to hack Rails internals is to have someone else do it for you, but I wanted things to work a little differently so there was still work to be done.\n
  • #56: The greatest thing about Ruby is that there is just a ton of open source out there. No matter what you&amp;#x2019;re doing, one of the most helpful things you can do to learn more is track down the most similar open-source project to what you&amp;#x2019;re working on and read their code. It&amp;#x2019;s really invaluable experience, even if they aren&amp;#x2019;t doing things the same way you want to or are working towards a different goal.\n
  • #57: Ok, so let&amp;#x2019;s take a look at the route conditions code and how we hook into it. [LIVECODE]\n
  • #58: So we&amp;#x2019;ve really only scratched the surface of routing here. To really get into the nuts and bolts I really recommend reading the posts on Jamis Buck&amp;#x2019;s blog; there&amp;#x2019;s enough there to be an entire tutorial session on its own.\n
  • #59: \n \n
  • #60: Once again my experience with this comes from writing a plugin, this time just to make my life easier when making Rails apps! UberKit provides some UI helpers that make it really easy to build navigation menus and forms in Rails apps.\n
  • #61: The UberKit includes UberMenus, which is a set of helpers designed to make creating navigation menus super-easy and UberForms, which provides a custom form builder to automatically generate label HTML etc.\n
  • #62: These things highlight a great aspect of Rails: much of the functionality is built to be extended, modified, and improved. We&amp;#x2019;ll look at some of the ways this is exposed as we go through each of the parts of creating the UberKit.\n
  • #63: Helpers are usually used for little methods to dry up little parts of your code. But with the right approach, they can be used as powerful interface building blocks that can be re-used from application to application.\n
  • #64: So when I started trying to learn about block-enabled helpers, the most obvious place to look was the one that all Rails developers use: form_for.\n
  • #65: The CaptureHelper is invaluable in advanced helper writing. It allows you to grab the output of arbitrary blocks of view code and store it in a variable. It&amp;#x2019;s how content_for works, but it can be repurposed to make some powerful helpers for us!\n
  • #66: What we basically want is a really readable way to write out a menu so that it automatically becomes well formed state-aware semanticHTML that we can easily style.\n
  • #67: The way we&amp;#x2019;ll do this is we&amp;#x2019;ll create a custom builder class that collects input from the user, then builds output. By doing this we give ourselves greater control over the construction of the output than simply outputting as we go.\n
  • #68: So let&amp;#x2019;s make it happen! [LIVECODE]\n
  • #69: Form Builders are a part of Rails that is built to be extended, but not really well documented in that way.\n
  • #70: So a form builder is a class that generates the components of a form. Most commonly it&amp;#x2019;s the class instantiated in the form_for helper.\n
  • #71: So this isn&amp;#x2019;t exactly a brand new idea. I learned the basics of extending form builders from a tabular form builder plugin.\n
  • #72: Here we&amp;#x2019;ll really benefit more from going straight into the code so let&amp;#x2019;s get started!\n
  • #73: \n \n
  • #74: and ruby&amp;#x2019;s a great language to work with and extend. however\n
  • #75: most of rails is advanced ruby, and you&amp;#x2019;re advised to learn the language in and out before you modify the internals. you should have the ruby hook methods at your fingertips, and should be comfortable rolling your own classes and modules.\n
  • #76: never, ever override the source code directly, always create new files and modules and include them judiciously -- this will help you upgrade later. \n
  • #77: whatever bit of code you&amp;#x2019;re modifying, make sure you know it IN AND OUT. don&amp;#x2019;t touch code that you have no idea what its doing, it&amp;#x2019;ll save you a lot of hassle. \n
  • #78: test your changes a lot, and in the same vein, read the tests for whatever code you&amp;#x2019;re modifying so you know what it&amp;#x2019;s REALLY about.\n
  • #79: and finally -- i&amp;#x2019;m preaching to the choir, but keep your code beautiful, concise and clear -- all three of these characteristics are not mutually exclusive \n