So you've consulted the online documentation. And you were at the head of the line for the beta book. You know how to use Rails to make magic happen. But your curiosity is getting the best of you this time, which is an altogether good thing for a programmer. It's not enough just to know that your code works. You want to know what goes on behind the Rails curtain. Then perhaps you'd like to hack it, because hacking is a way of learning how something works. Or maybe you think you've stumbled on a Rails bug, but you'd like to know for sure before you cry foul. Or perhaps you'd just like to become a better Ruby programmer. Here's the good news: Ruby and Rails want to help you.
Just this morning I was reminded of how empowered I feel using Rails. While running some database tests, I noticed that when the test fixtures were loaded the resulting SQL wasn't being logged in the test.log file. After the test fixtures are loaded, SQL logging happens as I expect. I hadn't noticed this before because it wasn't important. It's important now that I have a slew of tests that I want to run as fast as possible. (More on how to do that in an upcoming blog.) To get some insight into how the tests could be tuned, I'd like to see what SQL is being used. So, am I just not using the required incantation to turn on SQL logging when test fixtures load? Or is there a bug somewhere in the SQL logging?
Time to go dumpster diving in the Rails code. It turns out, the logger is explicitly set to only log errors while loading the test fixtures so that the log doesn't become cluttered with SQL statements during ramp-up.
old_logger_level = ActiveRecord::Base.logger.level ActiveRecord::Base.logger.level = Logger::ERROR
Then before the method ends, the logger is reset:
ActiveRecord::Base.logger.level = old_logger_level
It makes sense given that you're in test mode, and generally you could care less what gyrations Rails has to go through to load your test fixtures.
So the Rails code is open source, but that's just half of the story. Having located the code that temporarily turns down the logging level, I wanted to change the code to crank up the logging level for my experiments. Easy enough; I just comment out the line that turns down the logging level.
# ActiveRecord::Base.logger.level = Logger::ERROR
Realize that this code is deep in the bowels of ActiveRecord---the bottom-most layer in Rails. Now, what do I have to do to see my changes in action? Just one thing: run the tests that load my test fixtures. Things I don't have to do first include recompiling ActiveRecord and its dependencies, munging a CLASSPATH, and copying around JAR files. Much of this is a credit to Ruby as a dynamically-typed, interpreted language. But it's also a testament to how well Rails weaves together all of its components by default.
I'm fully aware that what I'm suggesting here isn't unique to Rails. Any interpreted program is easy to change and run. But what I'd ask you to consider is the subtle, but empowering, effect you get when you mix open source, an interpreted language, and a full-stack web framework with layers that work seamlessly together. That's part of what makes Rails a "you've gotta try it to understand" experience. The way multiple small advantages reinforce each other to produce a huge leap forward is hard to grasp until you've experienced it.
I'd also encourage you to study the Rails code just for fun. There's a lot of incredibly cool stuff going on in there, and just reading the code will make you a better Ruby programmer. You shouldn't be afraid to take a peek; it's good code. Being able to read, tweak, and run the Rails code with ease drastically lowers the price of participation. Indeed, David mentioned to me that they get patches from people who came to the framework the very same day. And I think he might just get a patch from me that allows future programmers to change the logging behavior of tests without commenting out source code.
In much the same way that the web took off because of "View Source", Rails is taking off because it lowers the barrier to entry and holds nothing back.