Example
Role -> hasMany -> User
If I want to get all users with a specific role I would normally do something like this:
$role = Role::findOrFail(1);
User::where('role.id', $role->id)->get()
or
User::where('role_id', $role->id)->get()
My question is: Is there any way to achieve that without using role_id
or id
. I want to just use the $role
object. Something like this would be great:
User::where('role', $role)->get();
I know I can use $role->users
, but I leaving this out, because I cannot use that if I have multiple belongsTo relations that I want to query.
Example
$model->where('otherModel', $otherModel1)->where('differentModel', $differentModel1)->get();
Background
A solution like this would help a lot, if you want to rename a primary or a foreign key or if your application has keys with counterintuitive names.
User::where('role', $role)->get();
You can't do this or achieve this directly. That is because you are comparing a column (role
) to a hole object. What you could do is define Local Scopes.
I know I can use $role->users, but I leaving this out, because I cannot use that if I have multiple belongsTo relations that I want to query.
Actually, in this case you are not making use of a belongsTo()
relationship but a hasMany()
one (the opposite). Again, you could create Local Scopes in order to keep constraining your query to get the users that match your conditions.
An example using a custom column/value search as you suggested in the last part of your question:
/** User.php */
public function hasRoleScope($query, $column, $value)
{
return $query->where("role.{$column}", '=', $value);
}
Then you could do:
/** AnyController.php */
User::has_role('name', 'admin')->get();
// equivalent to: User::where('role.name', '=', 'admin)->get();
You could keep define another one:
/** User.php */
public function scopeActive($query, $value)
{
return $query->where('active', $value);
}
Then you could do:
/** AnyController.php */
User::active(true)->get();
// equivalent to: User::where('active', true)->get();
The interesting part? You can combine the scopes:
/** AnyController.php */
User
::active(false)
->has_role('id', 23)
->get();