As I was upgrading some code to the new ActiveRecord syntax (which is beautiful by the way), I ran into an issue. The query worked perfectly fine before with the
find() call returning an array, but as I moved to the new syntax, ActiveRecord returns a Relation instead.
My query was fairly simple, and I just wanted to determine if the results were empty or not. We are using this code in our Senior Project, a simple web application for SIUe’s campus to make campus tour management a whole lot easier. We have several different areas where we need to query for the available tours, or all the tours in a given calendar month, etc. I made the query before where it would return an array. This new syntax ended up returning a Relation to the
@tours variable. A call to
@tours.empty? actually gave me this error:
undefined method 'zero?' for #
What was weird, was if I added this line (or anything else that used
@tours) the error never crept up again:
Internally in Rails, when you do a group query, you’re changing the type of the
count variable inside the Relation class. Normally it’s a simple Integer that keeps track of how many objects are returned if the results haven’t been loaded yet. Once you make a call to it, the results are loaded, and the
empty? no longer relies on the count variable as it can use the length of the results array instead.
Since a group returns an
ActiveSupport::OrderedHash as the type for the count variable, this causes a problem. The
zero? is implemented for
Numeric types, but not an
The solution to this is to simply patch Rails’
ActiveRecord::Relation like so: Simply check the type to make sure it is
Numeric and continue using
zero?, otherwise we should check to see if the count is
empty? for the case where count is an
OrderedHash or even some other type.
Hopefully my patch gets pulled into Rails 3.0.6 core! I’ve got my fingers crossed.comments powered by Disqus