Jeremy, thanks for the considered response.

On Thursday, 29 May 2014 01:07:18 UTC+9:30, Jeremy Evans wrote:
>
> On Wednesday, May 28, 2014 7:46:17 AM UTC-7, Andrew Hacking wrote:
>>
>> Hi,
>>
>> I am finding that when using the association_pks plugin that I am getting 
>> 1+N queries on many_to_many associations.
>>
>> When using eager loading (either explicitly or with the tactical eager 
>> loading plugin) the eager loaded dataset is not used.
>>
>> After reading the code of the plugin I noticed that the join table is 
>> used and that select_map() is called on it to get the foreign keys. This 
>> results in a separate query for each record in the original dataset.
>>
>> Ideally I don't want association_pks to eager join with the target table 
>> in the many_to_many case since all I want are the foreign keys from the 
>> join table, but I don't want 1+N queries either.
>>
>> The ideal approach would be to use the eager loaded or tactically eager 
>> loaded dataset for the many_to_many association if present, or tactically 
>> eager load just the join table (ie not the target table) and be able to use 
>> that dataset with each item in the original/parent dataset.
>>
>> This requires a fair amount of knowledge on the internals of how sequels 
>> eager loading works so any tips on the feasibility for doing something like 
>> this would be appreciated.  This is a very common use case in my json based 
>> web api where associated keys are both returned and modified so I'd like to 
>> make it work efficiently.
>>
>> I know I can just call map on the eager loaded association directly to 
>> get the ids but its both clumsy and the generated SQL does an extra join 
>> against the target table and returns more columns than I need. The 
>> association_pks plugin ought be able to do it  more efficiently by just 
>> eagerly pulling all the foreign keys from the join table in one go. 
>>
>> I'm also using Sequel 4.10, but it was behaving the same on earlier 
>> versions as well.
>>
>
> As select_map is a dataset method, it cannot work with eager loading.  To 
> have it work with eager loading, you'd have to change the *_pks getter to 
> look at the associated objects and call methods on them.  However, that 
> apparently isn't exactly what you want, as it does an extra join and 
> returns more columns than you need.  The more columns you can deal with 
> fairly easily by adding a eager callback: eager(:assoc=>proc{|ds| 
> ds.select(...)}), but if you want to avoid the extra join, there is nothing 
> in Sequel that will do what you want currently.   I'm not OK with changing 
> the default behavior, but I might consider adding an option to the plugin 
> so that it calls methods on the associated objects instead of using 
> select_map.
>
> For the most optimized approach, I would add a class method that takes an 
> array of objects and gets the associated pks for all of them in a single 
> query (select_hash_groups should work for that) and stores them in @*_pks 
> in each object, and then override the *_pks instance method to look for 
> @*_pks and return it if present (and call super if not).  I'm not sure if 
> something like that can be made generic easily, but if you come up with 
> something that you think will work in a generic way, please let me know.
>
> Thanks,
> Jeremy
>

-- 
You received this message because you are subscribed to the Google Groups 
"sequel-talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/sequel-talk.
For more options, visit https://groups.google.com/d/optout.

Reply via email to