Ian Haywood wrote:
> 
> Horst Herb wrote:
>> Now it performs just wonderfully even for complex nested multi-join tables
>>
>>   
> You mean using the :include parameter?
> 
> Just on that, one problem I've run into is you can't use :include on
> polymorphic joins.
> viz I have a class Log which is polymorphically joined to Drug, Note,
> Disease, etc. classes.
> 
> class Log < ActiveRecord::Base
>    belongs_to :object, :polymorphic => true
>    belongs_to :person
>    belongs_to :owner, :class_name => "Person", :foreign_key => "who"
> end
> 
> class Drug < ActiveRecord::Base
>   has_one :log, :as => :object
> end
> 
> class Disease < ActiveRecord::Base
>   has_one :log, :as => :object
> end
> 
> 
> 
> Doing l = Log.find(:all,:conditions=>['object_type = ?',
> 'Drug'],:include=>:object)
> throws ActiveRecord::EagerLoadPolymorphicError, as rails can't work out
> that on this
> query I just want Drug entries.
> 
> I can load each Drug instance separately, however (as you evidently
> discovered) this is too slow,
> as getting a list of n drugs becomes n+1 queries on the backend
> [gnumed had the same problem, but it has been fixed]
> 
> Drug.find_by_sql ('select * from drugs,logs where object_type=\'Drug\'
> and object_id=drugs.id')
> surprisingly, works, but rails doesn't handle the columns from logs
> properly (they can still be
> accessed, but aren't mapped to objects, as they are not part of Drug)
> Point is, it works, but loses a bit of it's
> ORM-ness in the process. The Python ORMs can avoid SQL here, but still
> can't correctly construct
> the result (a list of Log objects, with Log.object = a Drug object), but
> of course happy to be corrected
> here Tim.

Um, dunno, although at this point I would be pondering the wisdom of my
polymorphic Log class, which looks a bit like a metaclass to me (but
hard to tell without know how or what you use it for). A set of explicit
Log subclasses might be better, albeit involving more code.

The other approach is not to try to do everything in the back-end
database. Joins using Python dictionaries can be rather efficient where
at least one relation will fit in memory (and that's what the SQL engine
would be doing, anyway). Thus create your own polymorphic Log class
using the ORM just to return LOG table rows filtered by the appropriate
IDS using the IN operator? Too late to think to hard on this - requires
experimentation to find a good solution. But dogmatically trying to do
everything in SQL (either via the ORM or in hand-coded SQL) are not
always the best approaches, I think.

Tim C

_______________________________________________
Gpcg_talk mailing list
[email protected]
http://ozdocit.org/cgi-bin/mailman/listinfo/gpcg_talk

Reply via email to