Wow, Google Street View is totally great. And, as expected, some funny shit gets frozen in time at street level. Google is watching! Be cautious where you go, what you do! Try to remain calm, don't lose your head over it.
Caught In The Act
May 31, 2007 @ 04:01 PM by nap · 0 comments
ActiveRecord Delegation Pitfalls
May 30, 2007 @ 01:09 PM by nap · 0 comments
Delegation is a powerful concept. And it's a useful Ruby mixin, too. You can use the delegation mixin to easily expose related objects' methods as your own, which makes for much cleaner code than defining those methods by hand. However, there are some pitfalls to be aware of when dealing with delegation and the ActiveRecord lifecycle.
Here's a simple example of delegation in action:
class User < ActiveRecord::Base
has_one :homepage, :class_name => "Article"
delegate :url, :to => :homepage
end
my_user.url => url of the home page article for this user
Yes, we could just call my_user.homepage.url here too. But there are definitely some situations where you'd prefer not to do this. I won't attempt to relate my present situation to yours, as it's outside the scope of this discussion. Anyway, the point is that delegation can be used to make your life easier.
Here's where we get into trouble:
new_user = User.new
new_user.url
NoMethodError: You have a nil object when you didn't expect it!
The error occurred while evaluating nil.url
O NOES! What happened?
In a nutshell, when we use it in our model, the delegate class method defines a bunch of new instance methods on our User object. These methods simply forward their queries onto the target (:to) object. If the target object, at the present stage in the AR model lifecycle, happens to be nil, then we're trying to call a method on nil. The nil object doesn't have a url method, so we're toast.
def #{method}(*args, &block)
#{to}.__send__(#{method.inspect}, *args, &block)
end
How can we get around this? Well, court3nay opened a ticket to address this a while back. It was recently closed due to inactivity. I just reopened it, and added a small patch. Here's the difference in the way the mixin creates the delegated methods:
- #{to}.__send__(#{method.inspect}, *args, &block)
+ #{to}.__send__("nil?") ? nil : #{to}.__send__(#{method.inspect}, *args, &block)
Pretty simple really. We just test the delegation target to see if it's nil first. If it is, we return nil instead of trying to send it a message. Otherwise, we call the method on the target object and let the receiver worry about it.
Huzzah, we've successfully delegated the task of dealing with nil delegation targets! Way special, eh?
Sometimes It's The Little Things, pt 2
May 26, 2007 @ 08:26 AM by nap · 0 comments
So my first patch to Rails core was accepted yesterday. It's a tiny, tiny patch. All it does is add a :method parameter to the auto_complete_field helper so you can do RESTful autocompletion (the filter query should be submitted with a GET, not a POST, if you want to follow the REST conventions).
No big deal really, but it feels good to finally be able to "give back" to the community in a way other than blogging and IRC help. You know, with like, actual code that benefits people other than just me. I've contributed to a handful of Java and PHP-based OSS projects over the years, but this is officially my first contribution to a Ruby-based project, and that certainly feels like a step in the right direction.
Railsconf 2007 FTW
May 21, 2007 @ 02:12 PM by nap · 0 comments
Had a great time at Railsconf 2007! Just got back. A little jetlagged, and in need of (another) nap. In summary: lots of good presentations, superb microbrews, a hilarious zefrank performance, and a number of lurking lolcats.
Highlights for me included DHH's keynote, the Rails way 'live' performance by Jamis and Koz (although I have to politely disagree with them on the need for private ActiveRecord attributes), Ezra's deployment and scaling session, and the homesteading talk by Matthew Bass. Thanks to everyone who helped make it happen.
Also got to meet some fellow IRC peeps in person. Now ur tru idinty is nown to me, bewar!
Oregon
May 16, 2007 @ 02:22 PM by nap · 0 comments
So here I am in sunny Oregon. Around 1PM I hop on a train headed to Portland for RailsConf 07. Came out a few days early to catch up with my good buddy Ty in Eugene and work on the startup idea we've been banging around. And do some hiking, drinking, and dissecting of Heroes too, of course.
I kind of love being out here and yet still having my internal clock set to east coast time. I wake up "early" for a change, and bang out a nasty chunk of work before anyone else here is even awake yet. Otoh, I feel like an old man when I begin to falter around 11PM. Heh.
Anyway, I'm looking forward to the conference. I'll be attending the tutorials day tomorrow, specifically the scaling session with Joyent's Jason Hoffman as well as David Black's 'Routing Roundup'. If you see me, say hi.
Deconstructing date_select
May 09, 2007 @ 05:14 PM by nap · 0 comments
date_select and it's friend datetime_select are handy little helpers for rendering date selection widgets in your form, but what they hand back to your controller is a little bit unintuitive. If you're just going to go ahead and use update_attributes on your model, then ActiveRecord magically takes care of converting these to an appropriate Date or Time object for you. However, if you're not doing that, you'll find yourself staring at keys in your hash named odd things like "attribute(1i)".
Here's a handy little helper method, in case you ever need to manually reconstruct a Date object from the params:
# Reconstruct a date object from date_select helper form params
def build_date_from_params(field_name, params)
Date.new(params["#{field_name.to_s}(1i)"].to_i,
params["#{field_name.to_s}(2i)"].to_i,
params["#{field_name.to_s}(3i)"].to_i)
end
date = build_date_from_params(:published_at, params[:article])
Put this in your ApplicationController so inherited controller classes can access it, or (better yet) put it in a suite of helper methods to mix in to application.rb. Not exactly brain surgery here, but I'm a little surprised that there isn't something already baked into the helpers to do this.