Skip to content

Commit

Permalink
Move protected preload method to public so it can be used. Fixes #941 (
Browse files Browse the repository at this point in the history
  • Loading branch information
jwoertink authored Sep 1, 2023
1 parent 35c81b7 commit f84e111
Show file tree
Hide file tree
Showing 8 changed files with 48 additions and 23 deletions.
21 changes: 17 additions & 4 deletions spec/avram/preloading/preloading_belongs_to_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -14,26 +14,34 @@ describe "Preloading belongs_to associations" do
CommentFactory.create &.post_id(post.id)

comments = Comment::BaseQuery.new.preload_post
comment = comments.first.as(Comment)

comments.first.post.should eq(post)
comment.post.should eq(post)
comment.post_preloaded?.should eq(true)
Post::BaseQuery.times_called.should eq 1
end
end

it "works with optional association" do
with_lazy_load(enabled: false) do
employee = EmployeeFactory.create
EmployeeFactory.create
manager = ManagerFactory.create

employees = Employee::BaseQuery.new.preload_manager
employees.first.manager.should be_nil
employee = employees.first.as(Employee)
employee.manager.should be_nil
# This is a strange edge case when the object went through
# preloading, but no association exists
employee.manager_preloaded?.should eq(true)

Employee::SaveOperation.new(employee).tap do |operation|
operation.manager_id.value = manager.id
operation.update!
end
employees = Employee::BaseQuery.new.preload_manager
employees.first.manager.should eq(manager)
employee = employees.first.as(Employee)
employee.manager.should eq(manager)
employee.manager_preloaded?.should eq(true)
end
end

Expand All @@ -43,6 +51,7 @@ describe "Preloading belongs_to associations" do
comment = CommentFactory.create &.post_id(post.id)

comment = Comment::BaseQuery.find(comment.id)
comment.post_preloaded?.should eq(false)

expect_raises Avram::LazyLoadError do
comment.post
Expand All @@ -59,6 +68,8 @@ describe "Preloading belongs_to associations" do
comment = Comment::BaseQuery.new.preload_post(Post::BaseQuery.new.preload_comments).find(comment.id)

comment.post.comments.should eq([comment, comment2])
comment.post_preloaded?.should eq(true)
comment.post.comments_preloaded?.should eq(true)
end
end

Expand All @@ -69,6 +80,8 @@ describe "Preloading belongs_to associations" do
query = Comment::BaseQuery.new.preload_post

2.times { query.results }
comment = query.results.first.as(Comment)
comment.post_preloaded?.should eq(true)
end

it "works with uuid foreign keys" do
Expand Down
5 changes: 5 additions & 0 deletions spec/avram/preloading/preloading_has_many_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ describe "Preloading has_many associations" do

posts.results.first.comments.should eq([comment])
Comment::BaseQuery.times_called.should eq 1
posts.results.first.comments_preloaded?.should eq(true)
end
end

Expand All @@ -33,6 +34,7 @@ describe "Preloading has_many associations" do
results = posts.results
results.size.should eq(1)
results.first.comments.should eq([comment])
results.first.comments_preloaded?.should eq(true)
end
end

Expand Down Expand Up @@ -76,6 +78,7 @@ describe "Preloading has_many associations" do
it "raises error if accessing association without preloading first" do
with_lazy_load(enabled: false) do
post = PostFactory.create
post.comments_preloaded?.should eq(false)

expect_raises Avram::LazyLoadError do
post.comments
Expand All @@ -90,6 +93,7 @@ describe "Preloading has_many associations" do
posts = Post::BaseQuery.new.preload_comments

posts.results.first.comments.should eq([] of Comment)
posts.results.first.comments_preloaded?.should eq(true)
end
end

Expand All @@ -99,6 +103,7 @@ describe "Preloading has_many associations" do
posts = Post::BaseQuery.new.preload_comments

2.times { posts.results }
posts.results.first.comments_preloaded?.should eq(true)
end

it "does not fail when getting results multiple times with custom query" do
Expand Down
9 changes: 6 additions & 3 deletions spec/avram/preloading/preloading_has_many_through_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,11 @@ describe "Preloading has_many through associations" do
TaggingFactory.create &.tag_id(tag.id).post_id(post.id)
TaggingFactory.create &.tag_id(tag.id).post_id(other_post.id)

post_tags = Post::BaseQuery.new.preload_tags.results.first.tags
post = Post::BaseQuery.new.preload_tags.results.first
post.tags_preloaded?.should eq(true)

post_tags.size.should eq(1)
post_tags.should eq([tag])
post.tags.size.should eq(1)
post.tags.should eq([tag])
end
end

Expand All @@ -46,6 +47,7 @@ describe "Preloading has_many through associations" do
posts = Post::BaseQuery.new.preload_tags

2.times { posts.results }
posts.results.first.tags_preloaded?.should eq(true)
end
end

Expand Down Expand Up @@ -129,6 +131,7 @@ describe "Preloading has_many through associations" do
tag = TagFactory.create
original_post = PostFactory.create
TaggingFactory.create &.tag_id(tag.id).post_id(original_post.id)
original_post.tags_preloaded?.should eq(false)

Post::BaseQuery.preload_tags(original_post)

Expand Down
3 changes: 3 additions & 0 deletions spec/avram/preloading/preloading_has_one_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ describe "Preloading has_one associations" do

admin = Admin::BaseQuery.new.preload_sign_in_credential

admin.first.sign_in_credential_preloaded?.should eq(true)
admin.first.sign_in_credential.should eq sign_in_credential
end
end
Expand Down Expand Up @@ -49,6 +50,7 @@ describe "Preloading has_one associations" do
with_lazy_load(enabled: false) do
admin = AdminFactory.create
SignInCredentialFactory.create &.user_id(admin.id)
admin.sign_in_credential_preloaded?.should eq(false)

expect_raises Avram::LazyLoadError do
admin.sign_in_credential
Expand Down Expand Up @@ -95,6 +97,7 @@ describe "Preloading has_one associations" do
admin = Admin::BaseQuery.preload_sign_in_credential(admin)

admin.sign_in_credential.should eq sign_in_credential
admin.sign_in_credential_preloaded?.should eq(true)
end
end

Expand Down
5 changes: 3 additions & 2 deletions src/avram/associations.cr
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ module Avram::Associations
get_{{ assoc_name.id }}
end

protected getter? _{{ assoc_name }}_preloaded : Bool = false
# Returns `true` if the association has been preloaded
getter? {{ assoc_name }}_preloaded : Bool = false
private getter _preloaded_{{ assoc_name }} : {{ model }}?
end

Expand All @@ -30,7 +31,7 @@ module Avram::Associations
{% if !nilable %}
raise Avram::MissingRequiredAssociationError.new(self.class, {{ model }}) if record.nil?
{% end %}
@_{{ assoc_name }}_preloaded = true
@{{ assoc_name }}_preloaded = true
@_preloaded_{{ assoc_name }} = record
end
end
Expand Down
8 changes: 4 additions & 4 deletions src/avram/associations/belongs_to.cr
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ module Avram::Associations::BelongsTo

private macro define_belongs_to_private_assoc_getter(assoc_name, model, foreign_key, nilable)
private def get_{{ assoc_name.id }}(allow_lazy : Bool = false) : {{ model }}{% if nilable %}?{% end %}
if _{{ assoc_name }}_preloaded?
if {{ assoc_name }}_preloaded?
@_preloaded_{{ assoc_name }}{% unless nilable %}.not_nil!{% end %}
elsif lazy_load_enabled? || allow_lazy
{{ foreign_key }}.try do |value|
Expand Down Expand Up @@ -58,7 +58,7 @@ module Avram::Associations::BelongsTo
end

def self.preload_{{ assoc_name }}(record : {{ class_type }}, preload_query : {{ model }}::BaseQuery, force : Bool = false) : {{ class_type }}
return record if record._{{ assoc_name }}_preloaded? && !force
return record if record.{{ assoc_name }}_preloaded? && !force

new_record = record.dup
assoc = record.{{ foreign_key }}.try { |id| preload_query.id(id).first? }
Expand All @@ -78,7 +78,7 @@ module Avram::Associations::BelongsTo

def self.preload_{{ assoc_name }}(records : Enumerable({{ class_type }}), preload_query : {{ model }}::BaseQuery, force : Bool = false) : Array({{ class_type }})
ids = records.compact_map do |record|
if record._{{ assoc_name }}_preloaded? && !force
if record.{{ assoc_name }}_preloaded? && !force
nil
else
record.{{ foreign_key }}
Expand All @@ -87,7 +87,7 @@ module Avram::Associations::BelongsTo
empty_results = {} of {{ model }}::PrimaryKeyType => Array({{ model }})
{{ assoc_name }} = ids.empty? ? empty_results : preload_query.id.in(ids).results.group_by(&.id)
records.map do |record|
if record._{{ assoc_name }}_preloaded? && !force
if record.{{ assoc_name }}_preloaded? && !force
next record
end

Expand Down
12 changes: 6 additions & 6 deletions src/avram/associations/has_many.cr
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,13 @@ module Avram::Associations::HasMany

{% if through %}
def self.preload_{{ assoc_name }}(record : {{ class_type }}, preload_query : {{ model }}::BaseQuery, force : Bool = false) : {{ class_type }}
return record if record._{{ assoc_name }}_preloaded? && !force
return record if record.{{ assoc_name }}_preloaded? && !force

preload_{{ assoc_name }}(records: [record], preload_query: preload_query, force: force).first
end
{% else %}
def self.preload_{{ assoc_name }}(record : {{ class_type }}, preload_query : {{ model }}::BaseQuery, force : Bool = false) : {{ class_type }}
return record if record._{{ assoc_name }}_preloaded? && !force
return record if record.{{ assoc_name }}_preloaded? && !force

new_record = record.dup
new_record._preloaded_{{ assoc_name }} = preload_query.{{ foreign_key }}(record.id).results
Expand Down Expand Up @@ -102,7 +102,7 @@ module Avram::Associations::HasMany
{% else %}
def self.preload_{{ assoc_name }}(records : Enumerable({{ class_type }}), preload_query : {{ model }}::BaseQuery, force : Bool = false) : Array({{ class_type }})
ids = records.compact_map do |record|
if record._{{ assoc_name }}_preloaded? && !force
if record.{{ assoc_name }}_preloaded? && !force
nil
else
record.id
Expand All @@ -111,7 +111,7 @@ module Avram::Associations::HasMany
empty_results = {} of {{ model }}::PrimaryKeyType => Array({{ model }})
{{ assoc_name }} = ids.empty? ? empty_results : preload_query.{{ foreign_key }}.in(ids).results.group_by(&.{{ foreign_key }})
records.map do |record|
if record._{{ assoc_name }}_preloaded? && !force
if record.{{ assoc_name }}_preloaded? && !force
next record
end

Expand Down Expand Up @@ -171,10 +171,10 @@ module Avram::Associations::HasMany

private macro define_has_many_lazy_loading(assoc_name, model, foreign_key, through)
@_preloaded_{{ assoc_name }} : Array({{ model }})?
protected getter? _{{ assoc_name }}_preloaded : Bool = false
getter? {{ assoc_name }}_preloaded : Bool = false

def _preloaded_{{ assoc_name }}=(vals : Array({{ model }})) : Array({{ model }})
@_{{ assoc_name }}_preloaded = true
@{{ assoc_name }}_preloaded = true
@_preloaded_{{ assoc_name }} = vals
end

Expand Down
8 changes: 4 additions & 4 deletions src/avram/associations/has_one.cr
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ module Avram::Associations::HasOne

private macro define_has_one_private_assoc_getter(assoc_name, model, foreign_key, nilable)
private def get_{{ assoc_name.id }}(allow_lazy : Bool = false) : {{ model }}{% if nilable %}?{% end %}
if _{{ assoc_name }}_preloaded?
if {{ assoc_name }}_preloaded?
@_preloaded_{{ assoc_name }}{% unless nilable %}.not_nil!{% end %}
elsif lazy_load_enabled? || allow_lazy
{{ model }}::BaseQuery.new
Expand All @@ -54,7 +54,7 @@ module Avram::Associations::HasOne
end

def self.preload_{{ assoc_name }}(record : {{ class_type }}, preload_query : {{ model }}::BaseQuery, force : Bool = false) : {{ class_type }}
return record if record._{{ assoc_name }}_preloaded? && !force
return record if record.{{ assoc_name }}_preloaded? && !force

new_record = record.dup
assoc = preload_query.{{ foreign_key }}(record.id).first?
Expand All @@ -73,7 +73,7 @@ module Avram::Associations::HasOne

def self.preload_{{ assoc_name }}(records : Enumerable({{ class_type }}), preload_query : {{ model }}::BaseQuery, force : Bool = false) : Array({{ class_type }})
ids = records.compact_map do |record|
if record._{{ assoc_name }}_preloaded? && !force
if record.{{ assoc_name }}_preloaded? && !force
nil
else
record.id
Expand All @@ -82,7 +82,7 @@ module Avram::Associations::HasOne
empty_results = {} of {{ model }}::PrimaryKeyType => Array({{ model }})
{{ assoc_name }} = ids.empty? ? empty_results : preload_query.{{ foreign_key }}.in(ids).results.group_by(&.{{ foreign_key }})
records.map do |record|
if record._{{ assoc_name }}_preloaded? && !force
if record.{{ assoc_name }}_preloaded? && !force
next record
end

Expand Down

0 comments on commit f84e111

Please sign in to comment.