Extract Eloquent models scopes #226
Answered
by
antonkomarev
antonkomarev
asked this question in
Choose solution
-
This discussion created after the #224 Right now Eloquent model local scopes are located in Reactable & Reacterable traits and you cannot exclude them. To not add magical optional methods to models but let people easily use them we move them to the specific traits. There are 2 options:
|
Beta Was this translation helpful? Give feedback.
Answered by
antonkomarev
Jan 6, 2023
Replies: 2 comments 6 replies
-
Solution 1: Magical local scope methods in models traitsPros
Cons
Usage$usersReactedByMe = User::query()->whereReactedBy($myUser)->get(); Implementation<?php
declare(strict_types=1);
namespace App\Models;
use Cog\Laravel\Love\Reactable\Models\Traits\Reactable;
use Cog\Laravel\Love\Reactable\ReactableScopesTrait;
use Cog\Laravel\Love\Reacterable\Models\Traits\Reacterable;
use Cog\Laravel\Love\Reacterable\ReacterableScopesTrait;
use Illuminate\Database\Eloquent\Model;
final class User extends Model
{
use Reactable;
use ReactableScopesTrait;
use Reacterable;
use ReacterableScopesTrait;
} <?php
declare(strict_types=1);
namespace Cog\Laravel\Love\Reactable;
use Cog\Contracts\Love\Reacterable\Models\Reacterable as ReacterableInterface;
use Cog\Laravel\Love\ReactionType\Models\ReactionType;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
/**
* @mixin Model
*/
trait ReactableScopesTrait
{
public function scopeWhereReactedBy(
Builder $query,
ReacterableInterface $reacterable,
?string $reactionTypeName = null,
): Builder {
return $query->whereHas(
'loveReactant.reactions',
function (Builder $reactionsQuery) use ($reacterable, $reactionTypeName) {
$reactionsQuery->where('reacter_id', $reacterable->getLoveReacter()->getId());
if ($reactionTypeName !== null) {
$reactionsQuery->where('reaction_type_id', ReactionType::fromName($reactionTypeName)->getId());
}
}
);
}
public function scopeWhereNotReactedBy(
Builder $query,
ReacterableInterface $reacterable,
?string $reactionTypeName = null,
): Builder {
return $query->whereDoesntHave(
'loveReactant.reactions',
function (Builder $reactionsQuery) use ($reacterable, $reactionTypeName) {
$reactionsQuery->where('reacter_id', $reacterable->getLoveReacter()->getId());
if ($reactionTypeName !== null) {
$reactionsQuery->where('reaction_type_id', ReactionType::fromName($reactionTypeName)->getId());
}
}
);
}
} <?php
declare(strict_types=1);
namespace Cog\Laravel\Love\Reacterable;
use Cog\Contracts\Love\Reactable\Models\Reactable as ReactableInterface;
use Cog\Laravel\Love\ReactionType\Models\ReactionType;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
/**
* @mixin Model
*/
trait ReacterableScopesTrait
{
public function scopeWhereReactedTo(
Builder $query,
ReactableInterface $reactable,
?string $reactionTypeName = null,
): Builder {
return $query->whereHas(
'loveReacter.reactions',
function (Builder $reactionsQuery) use ($reactable, $reactionTypeName) {
$reactionsQuery->where('reactant_id', $reactable->getLoveReactant()->getId());
if ($reactionTypeName !== null) {
$reactionsQuery->where('reaction_type_id', ReactionType::fromName($reactionTypeName)->getId());
}
}
);
}
public function scopeWhereNotReactedTo(
Builder $query,
ReactableInterface $reactable,
?string $reactionTypeName = null,
): Builder {
return $query->whereDoesntHave(
'loveReacter.reactions',
function (Builder $reactionsQuery) use ($reactable, $reactionTypeName) {
$reactionsQuery->where('reactant_id', $reactable->getLoveReactant()->getId());
if ($reactionTypeName !== null) {
$reactionsQuery->where('reaction_type_id', ReactionType::fromName($reactionTypeName)->getId());
}
}
);
}
} |
Beta Was this translation helpful? Give feedback.
5 replies
-
Solution 2: Custom Eloquent Builder methods traitsPros
Cons
Usage$usersReactedByMe = User::query()->whereReactedBy($myUser)->get(); Implementation<?php
declare(strict_types=1);
namespace App\Models;
use Cog\Laravel\Love\Reactable\Models\Traits\Reactable;
use Cog\Laravel\Love\Reacterable\Models\Traits\Reacterable;
use Illuminate\Database\Eloquent\Model;
/**
* @method static UserEloquentBuilder query()
*/
final class User extends Model
{
use Reactable;
use Reacterable;
public function newEloquentBuilder($query)
{
return new UserEloquentBuilder($query);
}
} <?php
declare(strict_types=1);
namespace App\Models;
use Cog\Laravel\Love\Reactable\ReactableScopesTrait;
use Cog\Laravel\Love\Reacterable\ReacterableScopesTrait;
use Illuminate\Database\Eloquent\Builder;
final class UserEloquentBuilder extends Builder
{
use ReactableScopesTrait;
use ReacterableScopesTrait;
// Your other custom scopes
} <?php
declare(strict_types=1);
namespace Cog\Laravel\Love\Reactable;
use Cog\Contracts\Love\Reacterable\Models\Reacterable as ReacterableInterface;
use Cog\Laravel\Love\ReactionType\Models\ReactionType;
use Illuminate\Database\Eloquent\Builder;
/**
* @mixin Builder
*/
trait ReactableEloquentBuilderTrait
{
public function whereReactedBy(
ReacterableInterface $reacterable,
?string $reactionTypeName = null,
): Builder {
return $this->whereHas(
'loveReactant.reactions',
function (Builder $reactionsQuery) use ($reacterable, $reactionTypeName) {
$reactionsQuery->where('reacter_id', $reacterable->getLoveReacter()->getId());
if ($reactionTypeName !== null) {
$reactionsQuery->where('reaction_type_id', ReactionType::fromName($reactionTypeName)->getId());
}
}
);
}
public function whereNotReactedBy(
ReacterableInterface $reacterable,
?string $reactionTypeName = null,
): Builder {
return $this->whereDoesntHave(
'loveReactant.reactions',
function (Builder $reactionsQuery) use ($reacterable, $reactionTypeName) {
$reactionsQuery->where('reacter_id', $reacterable->getLoveReacter()->getId());
if ($reactionTypeName !== null) {
$reactionsQuery->where('reaction_type_id', ReactionType::fromName($reactionTypeName)->getId());
}
}
);
}
} <?php
declare(strict_types=1);
namespace Cog\Laravel\Love\Reacterable;
use Cog\Contracts\Love\Reactable\Models\Reactable as ReactableInterface;
use Cog\Laravel\Love\ReactionType\Models\ReactionType;
use Illuminate\Database\Eloquent\Builder;
/**
* @mixin Builder
*/
trait ReacterableEloquentBuilderTrait
{
public function whereReactedTo(
ReactableInterface $reactable,
?string $reactionTypeName = null,
): Builder {
return $this->whereHas(
'loveReacter.reactions',
function (Builder $reactionsQuery) use ($reactable, $reactionTypeName) {
$reactionsQuery->where('reactant_id', $reactable->getLoveReactant()->getId());
if ($reactionTypeName !== null) {
$reactionsQuery->where('reaction_type_id', ReactionType::fromName($reactionTypeName)->getId());
}
}
);
}
public function whereNotReactedTo(
ReactableInterface $reactable,
?string $reactionTypeName = null,
): self {
return $this->whereDoesntHave(
'loveReacter.reactions',
function (Builder $reactionsQuery) use ($reactable, $reactionTypeName) {
$reactionsQuery->where('reactant_id', $reactable->getLoveReactant()->getId());
if ($reactionTypeName !== null) {
$reactionsQuery->where('reaction_type_id', ReactionType::fromName($reactionTypeName)->getId());
}
}
);
}
} |
Beta Was this translation helpful? Give feedback.
1 reply
Answer selected by
antonkomarev
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Solution 2: Custom Eloquent Builder methods traits
Pros
Cons
Usage
Implementation