Module: ArLazyPreload::Relation
- Defined in:
- lib/ar_lazy_preload/active_record/relation.rb
Overview
ActiveRecord::Relation patch with lazy preloading support
Instance Attribute Summary collapse
- #lazy_preload_values ⇒ Object readonly
-
#preloads_associations_lazily ⇒ Object
writeonly
Sets the attribute preloads_associations_lazily.
Instance Method Summary collapse
-
#lazy_preload(*args) ⇒ Object
Specify relationships to be loaded lazily when association is loaded for the first time.
- #lazy_preload!(*args) ⇒ Object
-
#load ⇒ Object
Enhanced #load method will check if association has not been loaded yet and add a context for lazy preloading to loaded each record.
- #preload_associations(records) ⇒ Object
-
#preload_associations_lazily ⇒ Object
Lazily autoloads all associations.
Instance Attribute Details
#lazy_preload_values ⇒ Object
77 78 79 |
# File 'lib/ar_lazy_preload/active_record/relation.rb', line 77 def lazy_preload_values @lazy_preload_values ||= [] end |
#preloads_associations_lazily=(value) ⇒ Object (writeonly)
Sets the attribute preloads_associations_lazily
10 11 12 |
# File 'lib/ar_lazy_preload/active_record/relation.rb', line 10 def preloads_associations_lazily=(value) @preloads_associations_lazily = value end |
Instance Method Details
#lazy_preload(*args) ⇒ Object
Specify relationships to be loaded lazily when association is loaded for the first time. For example:
users = User.lazy_preload(:posts)
users.each do |user|
user.first_name
end
will cause only one SQL request to load users, while
users = User.lazy_preload(:posts)
users.each do |user|
user.posts.map(&:id)
end
will make an additional query.
66 67 68 69 |
# File 'lib/ar_lazy_preload/active_record/relation.rb', line 66 def lazy_preload(*args) check_if_method_has_arguments!(:lazy_preload, args) spawn.lazy_preload!(*args) end |
#lazy_preload!(*args) ⇒ Object
71 72 73 74 75 |
# File 'lib/ar_lazy_preload/active_record/relation.rb', line 71 def lazy_preload!(*args) args.flatten! self.lazy_preload_values += args self end |
#load ⇒ Object
Enhanced #load method will check if association has not been loaded yet and add a context for lazy preloading to loaded each record
25 26 27 28 29 30 31 32 33 34 35 36 |
# File 'lib/ar_lazy_preload/active_record/relation.rb', line 25 def load need_context = !loaded? result = super if need_context Context.register( records: ar_lazy_preload_records, association_tree: lazy_preload_values, auto_preload: preloads_associations_lazily? ) end result end |
#preload_associations(records) ⇒ Object
12 13 14 15 16 17 18 19 20 21 |
# File 'lib/ar_lazy_preload/active_record/relation.rb', line 12 def preload_associations(records) preload = preload_values preload += includes_values unless eager_loading? preload.each do |associations| ArLazyPreload::Preloader.new(records, associations).preload.each do |preloader_association| handle_preloaded_records(preloader_association.preloaded_records) end end end |
#preload_associations_lazily ⇒ Object
Lazily autoloads all associations. For example:
users = User.preload_associations_lazily
users.each do |user|
user.posts.flat_map {|post| post.comments.map(&:id)}
end
Same effect can be achieved by User.lazy_preload(posts: :comments)
46 47 48 |
# File 'lib/ar_lazy_preload/active_record/relation.rb', line 46 def preload_associations_lazily spawn.tap { |relation| relation.preloads_associations_lazily = true } end |