Relationship Condition
Refine is a paid package. To purchase, head to hammerstone.dev.
The Relationship Condition is an extension of the Numeric Condition and is for querying against the count of a related model.
RelationshipCondition::make('comment_count', 'Number of Comments') ->relationship('comments');
This condition has an id of comment_count
, a display of Number of Comments
and operates against the comments
relationship of the model your initial query is based on.
With this condition in place, the user will now be able to select e.g. [Number of Comments] [is greater than] [5]
.
Adding Query Restrictions
In the scenario where you want to scope your relationship down, you can pass a closure to the restrict
method.
RelationshipCondition::make('approved_comments', 'Number of Approved Comments') ->relationship('comments') ->restrict(function($query) { $query->where('approved', 1); });
Now instead of counting every related comment, it will only count comments where approved = 1
.
You can use this to create multiple instances of the same relationship with slight variations:
// ApprovedRelationshipCondition::make('approved_comments', 'Number of Approved Comments') ->relationship('comments') ->restrict(function($query) { $query->where('approved', 1); }); // PendingRelationshipCondition::make('pending_comments', 'Number of Pending Comments') ->relationship('comments') ->restrict(function($query) { $query->whereNull('approved'); }); // DeniedRelationshipCondition::make('denied_comments', 'Number of Denied Comments') ->relationship('comments') ->restrict(function($query) { $query->where('approved', 0); });
Using the Database Builder
The most common scenario for most filters is to return an instance of Eloquent\Builder
from your initialQuery
method. This is the class you get when you call e.g. Post::query()
.
If you are using the underlying Database\Builder
class as your initial query you'll also need to set the model where the relationship can be found.
Let's take a look:
class PostsFilter extends Filter{ public function initialQuery() { // If you're returning an instance of Database\Builder... return DB::table('posts'); } public function conditions() { return [ RelationshipCondition::make('comment_count', 'Number of Comments') ->relationship('comments') // Then you need to tell Refine that the `comments` // relationship you're referencing can be found // on the `Post` Eloquent model. ->on(Post::class) ]; }}
By calling the on
method of the Relationship Condition, you're informing Refine that the comments
relationship lives on the Post
model. Refine will then be able to use that information to derive the correct query and apply it to your base query.