:select and :include in find are incompatible


#1

I’ve run into a bit of a problem in a simple Rails app I’m working on.

In my case I’m using GeoKit. It extends options available to the find
method so that you can find by geographical distance. Very nice.

Problem is that it is incompatible with eager loading (:include).

There’s a blog post about it here:

A search on this forum shows many people having the same problems, with
this ticket often referenced:

http://dev.rubyonrails.org/ticket/5371

However this ticket was closed as WONTFIX.

I really don’t want to monkey-patch Rails as the blog post suggests. The
workarounds in Rails tickets don’t really apply to my situation.

I’m kinda stuck. Any suggestions?


#2

Sure… don’t eager load. Get your first result set… then use collect
to
grab the ids.

ids_to_find = @results.collect{|r| r.id}

Then you can use that array in another finder.

either like this:

more_results = Result.find(ids_to_find)

or

more_results = Result.find(:all, include =>[:other_stuff],
:conditions=>["
results.id in (?)", ids_to_find]

Would that work?


#3

Brian H. wrote:

Sure… don’t eager load. Get your first result set… then use collect
to
grab the ids.

Would that work?

It will! I was thinking about workarounds the wrong way. It’s still
inefficient but at least I can cut it down to about 2 queries (using the
sql IN parameter as you described). I was picturing myself going from 1
joined query to 100+ in order to check for my conditions matching, but I
never thought of simply doing a second “bulk find”.

Thanks!

Carl


#4

Brian H. wrote:

Sure… don’t eager load. Get your first result set… then use collect
to
grab the ids.

ids_to_find = @results.collect{|r| r.id}
more_results = Result.find(:all, include =>[:other_stuff],
:conditions=>["
results.id in (?)", ids_to_find]

I ran into some problems with this. The order is lost when using
“results.id IN”. My original query uses GeoKit to sort by distance, so
this field isn’t available in subsequent queries.

I could sort myself on the app side (rather than in the db) but that
doesn’t work with pagination. will_paginate replaces “find”, so
paginating after the “find” does not seem to be possible…


#5

I have created a plugin (my first) which monkey patches the
functionality submitted in http://dev.rubyonrails.org/ticket/7147 into
ActiveRecord, with several modifications.

It has been modified to use a new naming convention for :include
relationships.

Instead of using t[table_index]_r[column_index] I am now using a more
human readable convention of the form
table_name[index]__column_name.

Also, One of our requirements was the ability to extract an
ActiveRecord object hierarchy from an arbitrary (albeit following the
naming convention) result set. This is now possible through the
extract_objects(rows) method. We had several find methods which had to
be converted to PL/SQL functions for performance reasons. We can now
use connection.select_all to grab a result set, and run it through
extract objects to get a friendly active record collection (works with
nested includes as well)

I have not written comprehensives tests for it yet (i know, bad!) But
the source could be useful so I have decided to release it on
RubyForge at http://rubyforge.org/frs/?group_id=4193

It has been working well thus far in my application, YMMV. Please
give me feedback if you find any problems or have improvements.

Thanks,

Matt Kull

On Jul 30, 5:39 pm, Carl J. removed_email_address@domain.invalid
wrote:

I ran into some problems with this. The order is lost when using
“results.id IN”. My original query uses GeoKit to sort by distance, so
this field isn’t available in subsequent queries.

I could sort myself on the app side (rather than in the db) but that
doesn’t work with pagination. will_paginate replaces “find”, so
paginating after the “find” does not seem to be possible…

Po
sted viahttp://www.ruby-forum.com/.