Skip to content

Commit 471b28c

Browse files
committed
feat: preload foreign enumerable references
E.g. `User.join(:posts)`
1 parent 3640b84 commit 471b28c

2 files changed

Lines changed: 27 additions & 0 deletions

File tree

db_spec/pg/repository/query_spec.cr

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,15 @@ describe "Repository(Postgres)#query" do
133133
post.editor.not_nil!.uuid.should eq new_user.uuid
134134
end
135135
end
136+
137+
context "with foreign enumerable join" do
138+
user = repo.query(User.where(uuid: user.uuid).join(:authored_posts, select: '*')).first
139+
140+
it "preloads references" do
141+
user.authored_posts.should_not be_nil
142+
user.authored_posts.not_nil!.first.content.should eq "Blah-blah"
143+
end
144+
end
136145
end
137146
end
138147
end

src/atom/model/db_mapping.cr

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,24 @@ class Atom
133133
end
134134
{% end %}
135135

136+
# Preload foreign enumerable references
137+
{% for type in MODEL_REFERENCES.select(&.["enumerable"]).select(&.["foreign"]) %}
138+
# Check if current column is a reference marker (e.g. "_referrer")
139+
# Do not check for `!types_already_set` because "_referrer" takes higher precedence
140+
if column_name == "_" + {{type["name"].stringify}}
141+
142+
# Skip marker column because it doesn't have any data
143+
rs.read
144+
column_indexer.value += 1
145+
146+
# Read reference's attributes from further columns
147+
@{{type["name"]}} ||= {{type["true_type"]}}.new
148+
@{{type["name"]}}.not_nil!.push({{type["reference_type"]}}.new(rs, true, column_indexer))
149+
150+
next
151+
end
152+
{% end %}
153+
136154
# Unknown column in the result set
137155
raise DB::MappingException.new("#{{{@type}}}: cannot map column #{column_name} from a result set at index #{column_indexer.value}")
138156
end

0 commit comments

Comments
 (0)