The answers to this question explain that Model Scopes are not meant to return anything but a Query Builder instance and custom getters should be used to return Model instances.
Problem
In my case I have a User
and Contract
Model, where a User has many Contracts. The Contract periods may overlap, but at any given time, only the Contract with the latest start date should be considered valid (e.g. given Contract 1 from 2017-01-01
to 2017-07-31
and Contract 2 from 2017-06-01
to 2017-12-31
, for 2017-07-01
Contract 2 should be returned)
Current solution
Using scopes I always have to call ->first()
:
public function scopeByDate(Builder $query, $date) {
return $query->whereDate('start', '<=', $date)
->whereDate('end', '>=', $date)
->orderBy('start', 'desc');
}
public function scopeCurrent(Builder $query) {
return $this->scopeByDate($query, date('Y-m-d'));
}
...
$user->contracts()->byDate('some-date')->first();
$user->contracts()->current()->first();
(Worse?) alternative solutions
Otherwise I could make byDate()
and current()
static, accepting either a Builder
(looks bad to me) or a User
(even worse?) instance and manually pass the parameters like
public static function byDate(Builder $query, $date) {
return $query->whereDate(...)->whereDate(...)->orderBy(...)->first();
}
...
Contract::byDate($user->contracts(), 'some-date');
or
public static function byUserAndDate(User $user, $date) {
return $user->contracts()->where...->where...->orderBy(...)->first()
}
...
Contract::byUserAndDate($user, 'some-date');
Question
Is there some way I can call byDate()
or current()
directly on the query builder (relation) like scopes without passing additional parameters and return a model instance instead of a builder and having to call first()
every time?
from Newest questions tagged laravel-5 - Stack Overflow http://ift.tt/2gI4VZ5
via IFTTT
Aucun commentaire:
Enregistrer un commentaire