Project

General

Profile

Idea #2871

Updated by Tom Clegg almost 10 years ago

Example pages 
 * Show new/ready pipeline instance with lots of collections in script_parameters (e.g., GATK exome pipeline): this currently does multiple API lookups for each "select a collection" drop-down. 
 * Dashboard has a similar problem 
 * "Metadata" tab on a "show" page does multiple API lookups for each link it displays 

 Approach 
 * For a common type of lookup like "links pointing to X", create helper methods in ApplicationController to handle preloading and on-demand lookups. 

 <pre><code class="ruby"> 
 helper_method :links_for_object 
 def links_for_object object_or_uuid 
   uuid = object_or_uuid.is_a?(String) ? object_or_uuid : object_or_uuid.uuid 
   preload_links_for_objects([uuid]) 
   @all_links_for[uuid] 
 end 

 helper_method :preload_links_for_object 
 def preload_links_for_objects objects_and_uuids 
   uuids = objects_and_uuids.collect { |x| x.is_a?(String) ? x : x.uuid } 
   @all_links_for ||= {} 
   if not uuids.select { |x| @all_links_for[x].nil? }.any? 
     # already preloaded for all of these uuids 
     return 
   end 
   uuids.each do |x| 
     @all_links_for[x] = [] 
   end 
   # TODO: make sure we get every page of results from API server 
   Link.filter([['head_uuid','in',uuids]]).each do |link| 
     @all_links_for[link.head_uuid] << link 
   end 
 end 
 </code></pre> 

 In any controller/helper/view, when you expect to be looking up links for a set of objects: 

 <pre><code class="ruby"> 
 preload_links_for_objects @objects 
 </code></pre> 

 In any controller/helper/view when you need a list of links referencing a given object, instead of doing Link.where(), do: 

 <pre><code class="ruby"> 
 links_for_object(@object).each do |link| 
   if link.link_class == 'name' 
     # do stuff with link.name 
   end 
 end 
 </code></pre> 

 This will at least avoid doing multiple lookups for the same collection ID when rendering N select widgets, etc. Judicious use of "preload" will reduce round-trips further: e.g., combine all of the name/tag lookups for collections#index list into one API call by doing @preload_links_for_objects(@objects)@. 

Back