Skip to content

Instantly share code, notes, and snippets.

@godfat
Last active March 21, 2016 12:09
Show Gist options
  • Save godfat/9a2459d3212cc5671553 to your computer and use it in GitHub Desktop.
Save godfat/9a2459d3212cc5671553 to your computer and use it in GitHub Desktop.
dataset_module do
# User.one_to_one(:auth)
# User.eager_cursor(1000, :auth) do |user|
# user.auth # no additional query
# end
def eager_cursor rows_per_fetch=1000, *associations
cursor = use_cursor(rows_per_fetch: rows_per_fetch)
cursor.each_slice(rows_per_fetch) do |records|
associations.each do |assoc|
refl = model.association_reflection(assoc)
case refl[:type]
when :one_to_one
EagerCursorOneToMany
when :many_to_one
EagerCursorManyToOne
else
raise "Cannot handle: #{refl[:type]}"
end.new(records, refl).load
records.each do |r|
yield(r)
end
end
end
end
class EagerCursor < Struct.new(:records, :reflection)
def load
associations = reflection.associated_class.
where(association_key => records.map(&record_key)).all
records.each do |r|
if i = associations.find_index(&method(:find).curry[r])
a = associations.delete_at(i)
r.associations[reflection[:name]] = a
end
end
records
end
private
def find record, association
record.public_send(record_key) ==
association.public_send(association_key)
end
end
class EagerCursorOneToMany < EagerCursor
private
def association_key; reflection[:key] ; end
def record_key ; reflection.primary_key; end
end
class EagerCursorManyToOne < EagerCursor
private
def association_key; reflection.primary_key; end
def record_key ; reflection[:key] ; end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment