Modify Relation Manager query and get data that are not only related to ownerRecord

I am making an application where I have a Category, Product, Variation models. A category can have many variations and the product can have many variations as well. So we are talking about a morphMany relationship. Inside the ProductResource I have a VariationRelationManager which by default works just fine. However I want to modify the query and also get the variations that belong to the categories the Product belongs to. I face 2 problems here: a) The soft delete scope as well as the search do not work because of an orWhere statement in my query b) When I click on a record to edit, always the first record of the table is being selected for edit - it's like that the is not key identification on the records of the table. Here is how my Table method looks like ->modifyQueryUsing(function (Builder $query) { $categoriesIds = $this->getOwnerRecord()->getAllParentCategoriesIds(); // Recursively get parent categories ids $overrideIds = $this->getOwnerRecord()->variations()->whereNotNull('override_id')->pluck('override_id'); return $query ->where('variant_type', VariantType::Base->value) ->orWhere(function ($query) use ($categoriesIds, $overrideIds) { return $query->where('variationable_type', Category::class) ->whereIn('variationable_id', $categoriesIds) ->whereNotIn('id', $overrideIds) ->where('variant_type', VariantType::Base->value); }); })
2 Replies
ashattack
ashattack7mo ago
It likely doesn't work due to the orWhere broadening the scope of the query more than intended. Could even result in unexpected records being included in the query which could result in why filament has issues with identifying each record uniquely in the table. Naively, you could wrap your conditions in a more controlled manner - something like the following where all conditions are encapsulated within a single where clause and grouped the conditions related to the categories with an additional nested orWhere which should ensure all the variations (directly attached to the product or its categories) are filtered under the same conditions. It's a bit ugly though and hard to maintain. Someone else here may have a better approach.
return $query
->where(function ($query) use ($categoriesIds, $overrideIds) {
$query->where('variant_type', VariantType::Base->value)
->where(function ($query) use ($categoriesIds, $overrideIds) {
$query->where(function ($query) {
$query->where('variationable_type', Product::class)
->where('variationable_id', $this->getOwnerRecord()->id);
})->orWhere(function ($query) use ($categoriesIds, $overrideIds) {
$query->where('variationable_type', Category::class)
->whereIn('variationable_id', $categoriesIds)
->whereNotIn('id', $overrideIds);
});
});
});
return $query
->where(function ($query) use ($categoriesIds, $overrideIds) {
$query->where('variant_type', VariantType::Base->value)
->where(function ($query) use ($categoriesIds, $overrideIds) {
$query->where(function ($query) {
$query->where('variationable_type', Product::class)
->where('variationable_id', $this->getOwnerRecord()->id);
})->orWhere(function ($query) use ($categoriesIds, $overrideIds) {
$query->where('variationable_type', Category::class)
->whereIn('variationable_id', $categoriesIds)
->whereNotIn('id', $overrideIds);
});
});
});
The above code should now check the following: 1. If the variant type is base and the variationable type is Product and the variationable id is the owner record id. 2. If the variant type is base and the variationable type is Category and the variationable id is in the categories ids and the id is not in the override ids.
Vazaios
VazaiosOP7mo ago
Hmm for some reason your query does not get me the data that are not related to the owner record
Want results from more Discord servers?
Add your server