Advertisement
Guest User

Untitled

a guest
Jun 19th, 2019
120
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 1.26 KB | None | 0 0
  1. module InflateBelongsTo
  2. # when you have an array of models, but want to include (or even map)
  3. # an associated resource, this method puts together a single query to
  4. # fetch the data, then appends it to the model, cutting down on total
  5. # database calls.
  6. # this does the exact same work as eager loading when you first query
  7. # for a set of models, but is useful for nested resources deeper than
  8. # one level, especially if you wish to get results conditionally
  9. #
  10. # models: the array of models whose foreign key relationship you wish
  11. # to inflate
  12. # key: the instance method used to get the foreign record
  13. # key is used to construct two methods:
  14. # - `#{key}_id` for getting foreign record's id
  15. # - `#{key}=` for assignment once we've fetched
  16. #
  17. # returns an array of all resources
  18. def inflate(models, key)
  19. key_id = :"#{key}_id"
  20. models = Array(models)
  21.  
  22. resource_ids = models
  23. .select { |m| m.respond_to?(key_id) }
  24. .map { |m| m.send(key_id) }
  25. .uniq
  26. .compact
  27.  
  28. resources = where(id: resource_ids)
  29.  
  30. resource_map = resources.map { |r| [r.id, r] }.to_h
  31.  
  32. models
  33. .select { |m| m.respond_to?(:"#{key}=") }
  34. .map { |m| m.send(:"#{key}=", resource_map[m.send(key_id)]) }
  35.  
  36. resources
  37. end
  38. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement