On Tuesday, June 25, 2019 at 4:09:36 PM UTC-7, Paul Martinez wrote:
>
> Occasionally a method will be passed a model, or an array of models, and 
> access (possibly nested) associations on those models. In certain cases it 
> may be difficult to update the code that originally fetches those models to 
> eager load the appropriate models, but we do want to ensure those 
> associations are eager loaded.
>
> The tactial_eager_loading_plugin 
> <https://sequel.jeremyevans.net/rdoc-plugins/classes/Sequel/Plugins/TacticalEagerLoading.html>
>  
> partially solves this problem by proactively fetching associations on a set 
> of models that were loaded together, but I'm hesitant to use it because it 
> removes control from the programmer to control exactly what gets loaded 
> when.
>
> I wrote a plugin that allows eager loading (including nested associations) 
> on an array of models that are already in memory. Here's a gist with the 
> code:
>
> https://gist.github.com/PaulJuliusMartinez/bd2a2c243dcd3b5990ccf2984dca12f5
>
> A more in-depth explanation of the plugin's capabilities from the above 
> gist:
>
> This plugin adds support for eager loading associations _after_ a record, 
> or
> multiple records, have been fetched from the database. It is useful for 
> ensuring
> nested associations are efficiently loaded when it is difficult to modify 
> the
> dataset used to initially fetch the data.
>
> Example usage:
>
>   artist = Artist.first
>
>   # SELECT * FROM albums WHERE artist_id = ?
>   # SELECT * FROM tracks WHERE album_id IN (?, ?, ?, ...)
>   Artist.eager_load(artist, albums: :tracks)
>
>   # No queries issued
>   artist.albums[2].tracks
>
> Additionally, an array of models may be passed in to eager load 
> associations for all
> of them:
>
>   albums = Album.dataset.limit(10).all
>
>   # SELECT * FROM tracks WHERE album_id IN (?, ?, ?, ...)
>   Album.eager_load(albums, :tracks)
>
> The plugin will traverse through associations already loaded to eager load 
> nested
> associations:
>
>   artist = Artist.first
>   artist.albums
>
>   # SELECT * FROM tracks WHERE album_id IN (?, ?, ?, ...)
>   Artist.eager_load(artist, albums: :tracks)
>
> This plugin supports the same capabilities as the regular eager method, 
> namely
> using procs as callbacks for filtering association dataset. If an 
> association has
> already been loaded, however, the proc will not apply to that dataset.
>
>
> This method is very similar to the private eager_load 
> <https://github.com/jeremyevans/sequel/blob/master/lib/sequel/model/associations.rb#L3324-L3374>
>  Dataset 
> method defined by the associations plugin.
>
> I think moving this method to become a Class method (as I've essentially 
> done in the plugin above) would make the incredible existing eager loading 
> functionality even more flexible and more powerful. It makes sense to 
> separate eager loading from the initial fetching of data. Nested 
> associations are likely paired with nested processing or nested code 
> structure, which means that the initial fetching of the data and accessing 
> of the association are far apart (in terms of lines of code or method 
> calls). This makes it difficult to ensure that data is properly eager 
> loaded, but by allowing this method to be used after models are fetched, it 
> makes it possible to move our intentions for fetching data closer to where 
> we actually use it.
>
> Obviously I don't expect this architectural change to be implemented 
> without significant deliberation. It's just a suggestion borne from 
> personal experience with a large Sequel codebase.
>

It seems like the implementation could be:

module ClassMethods
  def eager_load(a, *associations)
    a = [a] unless a.is_a?(Array)
    dataset.send(:eager_load, a, 
dataset.send(:eager_options_for_associations, associations))
  end
end

I don't see why there is a need to make an architectural change to move the 
method from the dataset to the class.  In general, that should make things 
less flexible, as the current architecture allows for custom behavior per 
dataset.  Can you explain why there is a need to move the eager_load method 
from dataset method to class method, instead of having the class method 
call the dataset method?

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 https://groups.google.com/group/sequel-talk.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/sequel-talk/8d7e0269-e61d-4d91-ab8f-998be76557dc%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to