Using Warehouse(2007-08-09)
A few weeks ago, the guys at ActiveReload released Warehouse, a web-based Subversion repository management and browsing tool. You may know ActiveReload for the Lighthouse bug tracking system, which has been out for several months, or from the fact it’s a small company made up of Rick Olson (rails-core member and prolific purveyor of plugins) and Josh Goebel (who generously gave us Pastie).
I love both of these tools, for several reasons. First off, they’ve been built with integration in mind. They both have APIs (especially Lighthouse), and hooking them into tools like Campfire is trivial (and
My Thanks; An Aside(2007-08-07)
I’d like to offer my sincere thanks to those of you who have contacted me this week offering your condolences for the sudden and unexpected death of my youngest brother, Tristan.
As you might imagine, this came as an unbelievably hard blow to my family—but the outpouring of support received the last few days has helped me more than I can say (in the very least, offering a bit of human interaction).
My very sincere thanks to all of you. Don’t take anything for granted.
Bruce
PS. Now, back to the regularly scheduled [and considerably more cheery] program…
Finding Stale Tables(2007-08-01)
Here’s a simple rake task to help you find unused db tables lying around in your application. Keep in mind it’s just a guess, showing any table that doesn’t constantize; if you’re using habtm tables, unconventional table names, or other such things, expect to see them show up as well.
<notextile> namespace :app do namespace :stale do task :tables => :environment do tables = ActiveRecord::Base.connection.tables.reject do |table| table.classify.camelize.constantize rescue nil end - %w(schema_info) if tables.any? $stderr.puts "The following may be stale:" puts tables else $stderr.puts "No stale tables found" end end end end </notextile>
acts_as_texan :bruce(2007-07-18)
Okay, so I totally stole that from Adam Keys and the crowd up at Dallas.rb—but it’s true … I’ve just “finished” my move to Austin, TX, finally ending months of planning, hair pulling, and various other acts of torture that revolve around getting a family with two small children across several states.
By “finished,” of course I really mean I’m sitting in a hotel awaiting keys to the new house and the arrival of everything I own—but you get the point. I’m here, at least in body, and trying to come to grips with living in a completely new place.
So, if you’re around Austin, drop me a note; I’m lucky in that I already know a few people, but development is a social pursuit … so bring on the contacts :-)
Pownce, off the cuff(2007-07-06)
A few days ago I started to play around with Pownce, a recent new player in the ever expanding social webapp scene, roughly similar to Twitter.
I was a bit sceptical starting out, for three reasons.
- The word “social” can easily mean “recycled crap” at this point in the game
- It’s hard for me to think of Kevin Rose (part of the Pownce team) without thinking of the huge volume of vapid script kiddies that hang on his every word, or the general quality of Digg comments (not directly his fault, of course)
- To be truthful, it’s built on Django, and as an ex-Pythonista and passionate Rubyist we know what framework I prefer.
Now, on to reality and a few days later…
The featureset is pretty compelling. With finer grained dissemination controls, a first class “reply” feature, and the obvious benefits of having message types like Event and File, Pownce is already far less of a “toy” application than Twitter feels after several months of regular use. The fact Pownce offers a Flickr-like pro subscription is also nice, since it shows some forethought occurred as to monetization—which will hopefully stave off some scalability issues through generous use of hardware/staffing as well as limit advertising.
The design, in my opinion, is certainly better than Twitter’s. Twitter’s tiny hairline-bordered sidebar with the kitschy palette of friends is habitually annoying and not particularly intuitive, whereas Pownce’s interface, while certainly not perfect, seems reasonably put together.
Of course everything isn’t rosy; I ran into a few small issues, including it inexplicably not being able to handle PNG profile images - but it seems to be pretty stable for what’s most certainly a newly released application. I’d like to see some further development - like a published and open API with integration with other services, but as a developer I understand these things take time.
So, to wrap up, let’s address my initial concerns:
- On social sites: although these are commonly used elements on social sites, this seems to integrate them in what feels like a very cohesive interface, and keeps things simple without making them too stupid.
- On Kevin: he’s just a part of a team, and thanks to the friend controls, I can insulate myself from the aforementioned hangers-on and comment [message] trolls.
- On Django: liking or not liking an application for the underlying framework is pretty stupid; understanding when you’re the developer and when you’re the user is smart, so I’ll step back and see Pownce for what it is; a pretty clever use of a framework I don’t prefer but can appreciate.
You can find me at Twitter here and Pownce here. If you’d like a Pownce invitation, contact me—there’s a chance I have one handy.
Locking down The Move(2007-06-21)
So, after a couple months of trying to figure it out, it looks as if my move to the Austin area is finally starting to take shape.
A week or so into July, we start the exciting trip southeast—this time trading in the normal drive through thrill-a-minute Kansas for the post-apocolypsesque terrain of West Texas.
We’ve secured a nice 4 bedroom house near the office, several coffeeshops, and Lake Travis, thereby meeting my laziness, caffeination, and occasional-periods-of-sunshine needs.
Best Garlic Press(2007-06-04)
I love garlic, and so does my wife (which I suppose is lucky for both of us), and together we go through a vast amount of it every month. For the past few years I’ve been hand-mincing my garlic with a chef’s knife or santoku because of mixed results I’ve gotten from number of garlic presses—hard to clean, hard to use, not durable, etc.
I’m a fair hand with a knife, so mincing manually isn’t a huge problem, but due to the volume of garlic I have to process (since we eat largely mediterranean meals) it got a bit tiring.
So… I decided to give garlic presses another try, purchasing a Rösle. This is by far the best press I’ve ever used, and I highly recommend it to fellow garlic eaters.
folder_for: A Controller DSL(2007-06-02)
Over the last year or so, I’ve spoken at a number of meetings and conferences (including The Rails Edge and RailsConf) about view layer concerns, and on several occasions have given a folder interface example when speaking about controller domain specific languages. Since I’ve received several requests, here’s some information on the example (and the code, of course).
First of all, here’s the source
The Slimy Used Car Salesman App (beta)
For our example, let’s pretend for a moment that we’re developing an application that will serve as a local listing of used cars for sale. After talking with the client, we’ve determined that in makes sense that a folder-style interface to be used on a few pages, most notably when viewing the information for a specific car. Folder interfaces aren’t hard, but they can be tedious—so we’re going to employ a DSL so we can easily create them with a minimum of hassle. We could do this purely in the view layer, but we’d like the flexibility to add custom code for individual tabs in the controller, and don’t want to have to remember a series of helpers that we’ll need in views.
Using this plugin, we can do something like the following:
class CarsController < ActionController::Base
# ...
folder_for :show do
tab "General Information" do
@score = current_user.score_for_car(@car)
end
tab "History"
tab "Photos"
end
# ...
end
What we’re doing here is defining a folder to be displayed for the show action, with 3 tabs. On the first tab, General Information, we’d also like to calculate a score for the car, based on the currently signed-in user’s preferences.
So, what happens now?
We have to define the content of each tab. In the past, we would have one view template to work with:
cars/
show.html.erb
and would have had to manually render the partial for the currently selected tab, based on a parameter, and handled setting the default tab, not to mention the mechanics of switching tabs. Perhaps, if we were exceedingly lazy, we would have just had a big, ugly if, elsif statement in our template as well, conditionally rendering content for tabs. Ick.
How this works now, by convention, is that we break up our templates/partials like:
cars/
show.html.erb
show/
_general_information.html.erb
_history.html.erb
_photos.html.erb
and our show.html.erb might look something like:
<h1><%= @car.title %></h1> <p><%= @car.summary %></p> <%= folder %> <p>Some information below the folder...</p>The folder helper essentially says “put the folder here,” and the content that’s inserted consists of:
- A set of easily-styleable, functional tabs (a ul), with the current tab selected (through a CSS class)
- The content from the appropriate tab partial inserted in a div within the folder
The concerns of the folder system - the fact that it involves the use of params[:tab], the first tab is the default, and links need to be generated to switch from tab to tab - is not something you need to care about; these are mundane details that this level of abstraction allows you to ignore.
Another thing you may have noticed is the fact that @car is available for use—both within the tab definitions in the controller (where, in our example, we set @score) and in views. How is this handled? Using REST conventions (the fact we’re doing this within CarsController), the folder knows that there should be a Car model, and that it should set @car using Car.find(params[:id]). Once again, a mundane detail that remains beneath your notice.
Caveat Emptor
It’s important that I point out a few details on the limitations of this plugin—and very unapologetically, since it’s an example and not a release.
- Cases where a record need not be queried (ie, we don’t need @car), or multiple records are needed (ie, if we were setting up a folder on index) are not handled by this implementation—but could easily if an options hash argument was handled by folder_for. I sacrificed completeness for [some semblance of] clarity.
- There is no support for multiple folders-per-view (though there is support for multiple folders per controller), since I think that’s a fairly stupid interface decision, so adding support for it is stupid, too.
- The code may or may not work with Rails versions prior to support for .html.erb template extensions (ie, the old .rhtml days)
- There’s probably a number of other limitations; feel free to extend as you see fit.
In My Defense
There are likely several of you reading this that are disturbed to see a folder reference within a controller, as this amounts to level type of MVC “separation of concerns” blasphemy in your very strict, very well-worn book of religious morals.
I’m here to tell you it’s okay, and you’ll recover in time.
Let’s keep in mind here that the MVC separation of concerns, while a great rule of thumb - is just that - and is not an ivory tower to be left unassailed in times of dire need. At times, it makes sense to allow abstractions to cross these boundaries for the sake of reducing our own overhead, and in the cause of developing your own app-wide domain specific language—something, that in my book, is the principal sign of a good Rails developer (for what it’s worth).
Malleable Fun (or, the Moral of the Story)
An important thing to remember when using Rails is that it sits on top of Ruby—something that’s so obvious that it’s moronic, but nonetheless something people seem to forget.
What this means is that you have this amazingly dynamic, expressive language at your fingertips, and you’re free to extemporize as you see fit, creating your own mini languages in a flash.
Think something sucks to do every time manually? Don’t. Write code to do it, or write code to write code to do it. You’re language crappiness quotient is remarkably low—are you taking advantage of that, or have you fallen into old patterns of suck-it-up-and-bear-it self-pity?
And that’s the Public Service Announcement of the day, thank you.
Donate through Pragmatic Studio(2007-05-18)
This morning at the RailsConf welcome talk, Chad gave an impassioned speech urging conference attendees to help “change the world” by donating to charity through Pragmatic Studio. Pragmatic Studio, known for their excellent commercial tutorials, raised over $10k through donations by attendees of their Guidebook yesterday.
This is something anyone can participate in, whether you have the opportunity to attend RailsConf or not. How much money can the community, as a whole, raise?
Donate at http://pragmaticstudio.com/donate/
When "V" is for "Vexing"(2007-05-18)
For those looking for the slides and code examples from the tutorial I presented with Marcel Molina, Jr on Thursday at RailsConf:
Here are the slides in PDF format; I’ll be posting the code for the folder_for controller DSL sometime later in the day. If you have any questions, comments, or just want to chat about the ideas that were covered, see my “contact information:/contact (or just catch me at the conference).
A few people have asked how to get the code for the Stencil Plugin that was mentioned; you can check it out via RubyForge SVN (YMMV; keep in mind it’s still somewhat “pre-release” a this point).
svn co svn://rubyforge.org/var/svn/stencil/trunk stencil


