Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- module InflateBelongsTo
- # when you have an array of models, but want to include (or even map)
- # an associated resource, this method puts together a single query to
- # fetch the data, then appends it to the model, cutting down on total
- # database calls.
- # this does the exact same work as eager loading when you first query
- # for a set of models, but is useful for nested resources deeper than
- # one level, especially if you wish to get results conditionally
- #
- # models: the array of models whose foreign key relationship you wish
- # to inflate
- # key: the instance method used to get the foreign record
- # key is used to construct two methods:
- # - `#{key}_id` for getting foreign record's id
- # - `#{key}=` for assignment once we've fetched
- #
- # returns an array of all resources
- def inflate(models, key)
- key_id = :"#{key}_id"
- models = Array(models)
- resource_ids = models
- .select { |m| m.respond_to?(key_id) }
- .map { |m| m.send(key_id) }
- .uniq
- .compact
- resources = where(id: resource_ids)
- resource_map = resources.map { |r| [r.id, r] }.to_h
- models
- .select { |m| m.respond_to?(:"#{key}=") }
- .map { |m| m.send(:"#{key}=", resource_map[m.send(key_id)]) }
- resources
- end
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement