Skip to content

Commit bd162d0

Browse files
authored
Merge pull request #456 from XaserAcheron/fix-empty-hasmanythrough
Fixed HasManyThrough relationships returning empty data array without 'include'
2 parents 748e0f0 + c45925b commit bd162d0

File tree

2 files changed

+41
-6
lines changed

2 files changed

+41
-6
lines changed

src/JsonApiDotNetCore/Internal/ResourceGraph.cs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -144,11 +144,18 @@ private IEnumerable<IIdentifiable> GetHasManyThrough(IIdentifiable parent, HasMa
144144
var throughProperty = GetRelationship(parent, hasManyThrough.InternalThroughName);
145145
if (throughProperty is IEnumerable hasManyNavigationEntity)
146146
{
147-
foreach (var includedEntity in hasManyNavigationEntity)
148-
{
149-
var targetValue = hasManyThrough.RightProperty.GetValue(includedEntity) as IIdentifiable;
150-
yield return targetValue;
151-
}
147+
// wrap "yield return" in a sub-function so we can correctly return null if the property is null.
148+
return GetHasManyThroughIter(hasManyThrough, hasManyNavigationEntity);
149+
}
150+
return null;
151+
}
152+
153+
private IEnumerable<IIdentifiable> GetHasManyThroughIter(HasManyThroughAttribute hasManyThrough, IEnumerable hasManyNavigationEntity)
154+
{
155+
foreach (var includedEntity in hasManyNavigationEntity)
156+
{
157+
var targetValue = hasManyThrough.RightProperty.GetValue(includedEntity) as IIdentifiable;
158+
yield return targetValue;
152159
}
153160
}
154161

test/JsonApiDotNetCoreExampleTests/Acceptance/ManyToManyTests.cs

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,34 @@ public async Task Can_Fetch_Many_To_Many_Through_GetById()
110110
Assert.Equal(tag.Name, tagResponse.Name);
111111
}
112112

113+
[Fact]
114+
public async Task Can_Fetch_Many_To_Many_Without_Include()
115+
{
116+
// arrange
117+
var context = _fixture.GetService<AppDbContext>();
118+
var article = _articleFaker.Generate();
119+
var tag = _tagFaker.Generate();
120+
var articleTag = new ArticleTag
121+
{
122+
Article = article,
123+
Tag = tag
124+
};
125+
context.ArticleTags.Add(articleTag);
126+
await context.SaveChangesAsync();
127+
128+
var route = $"/api/v1/articles/{article.Id}";
129+
130+
// act
131+
var response = await _fixture.Client.GetAsync(route);
132+
133+
// assert
134+
var body = await response.Content.ReadAsStringAsync();
135+
Assert.True(HttpStatusCode.OK == response.StatusCode, $"{route} returned {response.StatusCode} status code with payload: {body}");
136+
137+
var document = JsonConvert.DeserializeObject<Document>(body);
138+
Assert.Null(document.Data.Relationships["tags"].ManyData);
139+
}
140+
113141
[Fact]
114142
public async Task Can_Create_Many_To_Many()
115143
{
@@ -269,4 +297,4 @@ public async Task Can_Update_Many_To_Many_Through_Relationship_Link()
269297
Assert.Equal(tag.Id, persistedArticleTag.TagId);
270298
}
271299
}
272-
}
300+
}

0 commit comments

Comments
 (0)