I don't see any scopeCurrentlyAvailable scope in your code, but you are trying to use it.
Query Scope where $user->relationship->method() is true
I am trying to write a query scope to find all instances of the User model where the user's schedule indicates that they are available.
I have the User model, and a UserSchedule model. the User model has a method called isAvailable() that returns true or false if the UserSchedule indicates that a user is available on the current day of the week.
my UserSchedule:
class UserSchedule extends Model
{
use HasFactory;
protected $table = 'availability_user';
protected $guarded = [];
public function user(): BelongsTo
{
return $this->belongsTo(User::class);
}
public function get(): OpeningHours
{
return OpeningHours::create([
'monday' => $this->getDaySchedule('monday'),
'tuesday' => $this->getDaySchedule('tuesday'),
'wednesday' => $this->getDaySchedule('wednesday'),
'thursday' => $this->getDaySchedule('thursday'),
'friday' => $this->getDaySchedule('friday'),
'saturday' => $this->getDaySchedule('saturday'),
'sunday' => $this->getDaySchedule('sunday'),
'exceptions' => $this->exceptions(),
]);
}
private function monday(): array
{
return [$this->removeSeconds($this->monday_start).'-'.$this->removeSeconds($this->monday_end)];
}
private function getDaySchedule($day): array
{
if ($this->$day === 0) {
return [];
} else {
return [$this->removeSeconds($this->{$day.'_start'}).'-'.$this->removeSeconds($this->{$day.'_end'})];
}
}
private function exceptions(): array
{
return [];
}
private function removeSeconds($time): string|null
{
if ($time) {
return substr($time, 0, -3);
} else {
return null;
}
}
}
my User model:
class User extends Authenticatable implements \Spatie\Onboard\Concerns\Onboardable
{
use HasApiTokens,
HasFactory,
Notifiable,
HasRoles,
Billable,
\Spatie\Onboard\Concerns\GetsOnboarded;
/*
* ....
*/
public function schedule(): HasOne
{
return $this->hasOne(UserSchedule::class);
}
public function isAvailable(): bool
{
if ($this->schedule()->exists()) {
$schedule = $this->schedule->get();
$today = Carbon::now()->dayName;
return $schedule->isOpenOn($today);
} else {
return false;
}
}
/**
* Alters the query string so that only the
* users with a specific role are returned.
*
* @param $query
* @param $role
* @return void
*/
function scopeWithRole($query, $role): void
{
$query->whereHas('roles', function ($q) use ($role) {
$q->where('name', $role);
});
}
/**
* Alters the query string so that only the
* users whose schedule indicates they are
* available today are returned.
*
* @param $query
* @param $role
* @return void
*/
function scopeAvailableToday($query)
{
$query->where($this->isAvailable(), true);
}
}
What I am trying to do is create a query scope so that I can do something like this:
$availableUsers = User::currentlyAvailable()->get();
and get a collection of Users whose schedules indicate that they are available on today's day of the week.
But when I run the code in Tinker as is, with data that I know is accurate, I get this error:
$user = App\Models\User::currentlyAvailable()->get();
Illuminate\Database\QueryException with message 'SQLSTATE[42S22]: Column not found: 1054 Unknown column '' in 'where clause' (SQL: select * from `users` where `` = 1)'
That error you get when calling App\Models\User::currentlyAvailable() seems to be something you would get when calling App\Models\User::availableToday(), defined in scopeAvailableToday()
The first parameter of the where() method of a query object should be a string with colum name, but the function isAvailable() returns a boolean.
If that happens to be false, I can totally see eloquent making an empty string as column name, which is what you see in "select * from users where `` = 1"
Please or to participate in this conversation.