hasManyDeep with 'where' giving unexpected results
arjendejong12 opened this issue · comments
Arjen de Jong commented
Hi!
I've got the following relationship: Group
-> BelongsToMany -> Post
-> HasMany -> Document
.
I'm trying to get all documents in a group where the posts have a certain condition (published and not expired).
class Group extends Model
{
public function posts(): BelongsToMany
{
return $this->belongsToMany(Post::class);
}
public function documents()
{
return $this->hasManyDeep(Document::class, ['group_post', Post::class]);
}
public function availableDocuments()
{
// I wanted to use the scopes from the Post model here but I'm not sure how and if that is possible, so I've tried it with this.
return $this->documents()->where(fn ($query) => $query->where('posts.published_at', '>', now())->where('posts.author_id', auth()->user()->id))->orWhere('posts.published_at', '<=', now())
->where(fn ($query) => $query->whereNull('posts.expired_at')->orWhere('posts.expired_at', '>', now()));
}
}
class Post extends Model
{
public function scopePublished(Builder $query)
{
return $query->where(fn ($query) => $query->where('published_at', '>', now())->where('author_id', auth()->user()->id))->orWhere('published_at', '<=', now());
}
public function scopeNotExpired(Builder $query)
{
return $query->where(fn($query) => $query->whereNull('expired_at')->orWhere('expired_at', '>', now()));
}
public function groups(): BelongsToMany
{
return $this->belongsToMany(Group::class);
}
public function documents(): HasMany
{
return $this->hasMany(Document::class);
}
}
class Document extends Model
{
public function groups() {
return $this->hasManyDeepFromRelations($this->post(), (new Post)->groups());
}
public function post(): BelongsTo
{
return $this->belongsTo(Post::class);
}
}
The following query returns documents that belong to a post that does not belong to the specific group:
$this->group // Group::find(1); for example
->availableDocuments()
->with(['post', 'post.author'])
->where('documents.type', 'url')
->orderBy('created_at', 'desc')
->paginate($this->tableRecordsPerPage, ['*'], 'linksPage');
Any idea what I'm doing wrong?
Arjen de Jong commented
I think I've got it working the way I want it to now. Could you check if this is the way you intended it to work?
class Group extends Model
{
public function posts(): BelongsToMany
{
return $this->belongsToMany(Post::class);
}
public function availablePosts(): BelongsToMany
{
return $this->posts()->published()->notExpired();
}
public function documents()
{
return $this->hasManyDeep(Document::class, ['group_post', Post::class]);
}
public function availableDocuments()
{
return $this->hasManyDeepFromRelationsWithConstraints([$this, 'availablePosts'], [new Post(), 'documents']);
}
}
Jonas Staudenmeir commented
Looks good 👍