Traits avec PHP et Laravel
Je suis à l'aide de Laravel 5.1 et aimeriez avoir accès à un tableau sur le Modèle du Trait lorsque le Modèle avant, le modèle utilise les appends
tableau.
Je voudrais ajouter certains éléments à la ajoute tableau, s'il existe, de mon caractère. Je ne veux pas modifier le modèle afin d'atteindre cet objectif. Traits sont réellement utilisable dans ce scénario, ou devrais-je utiliser l'héritage?
array_push($this->appends, 'saucedByCurrentUser');
Ici est de savoir comment mon setup actuel fonctionne.
Trait
<?php namespace App;
trait AwesomeSauceTrait {
/**
* Collection of the sauce on this record
*/
public function awesomeSauced()
{
return $this->morphMany('App\AwesomeSauce', 'sauceable')->latest();
}
public function getSaucedByCurrentUserAttribute()
{
if(\Auth::guest()){
return false;
}
$i = $this->awesomeSauced()->whereUserId(\Auth::user()->id)->count();
if ($i > 0){
return true;
}
return false;
}
}
Modèle
<?php namespace App;
use App\AwesomeSauceTrait;
use Illuminate\Database\Eloquent\Model;
class FairlyBlandModel extends Model {
use AwesomeSauceTrait;
protected $appends = array('age','saucedByCurrentUser');
}
Ce que j'aimerais faire, c'est quelque chose à atteindre le même effet que l'extension d'une classe. J'ai un peu de traits similaires, de sorte que l'utilisation de l'héritage devient un peu laid.
trait AwesomeSauceTrait {
function __construct() {
parent::__construct();
array_push($this->appends, 'saucedByCurrentUser');
}
}
J'ai vu quelques solutions de contournement pour cemais aucune d'entre elles semblent mieux/plus propre que tout ajout de l'élément dans le tableau manuellement. Toutes les idées sont les bienvenues.
Mise à jour
J'ai découvert cette façon d'accomplir ce dont j'ai besoin pour un trait de caractère, mais il ne fonctionne que pour un seul trait et je ne vois pas l'avantage de l'utilisation de ce sur l'héritage.
trait
protected $awesomeSauceAppends = ['sauced_by_current_user'];
protected function getArrayableAppends()
{
array_merge($this->appends, $this->awesomeSauceAppends);
parent::getArrayableAppends();
}
Comment je suis actuellement à la manipulation de mon Modèle, pour ce qu'il vaut.
modèle
public function __construct()
{
array_merge($this->appends, $this->awesomeSauceAppends);
}
source d'informationauteur whoacowboy
Vous devez vous connecter pour publier un commentaire.
Traits sont parfois décrits comme des "compilateur assistée de " copier-coller"; le résultat de l'utilisation d'un Trait peut toujours être écrite comme valide de classe dans son propre droit. Il n'y a donc pas de notion de
parent
dans un Trait, car une fois que le Trait a été appliqué, ses méthodes sont identiques à celles définies dans la classe elle-même, ou importées à partir d'autres Traits en même temps.De même, comme le PHP docs dire:
En tant que tels, ils ne sont pas très approprié pour les situations où vous voulez mélanger dans de multiples variantes de la même pièce de comportement, car il n'existe aucun moyen pour les fonctionnalités de base et mixtes dans la fonctionnalité de parler les uns aux autres de manière générique.
Dans ma compréhension du problème que vous êtes en train d'essayer de résoudre est: est-ce
$appends
tableau correspondant à ces méthodesUne approche pourrait être de continuer à utiliser les Traits, et l'utilisation La réflexion de découvrir de manière dynamique les méthodes qui ont été ajoutés. Cependant, méfiez-vous de cette Réflexion a la réputation d'être plutôt lent.
Pour ce faire, nous avons d'abord mettre en œuvre un constructeur avec une boucle sur laquelle on peut raccorder simplement en nommant une méthode d'une manière particulière. Ce peut être placé dans un Trait de caractère qui lui est propre (sinon, vous pouvez sous-classe de la Éloquent
Model
classe avec votre propre version améliorée):Ensuite n'importe quel nombre de Traits de la mise en œuvre de nom différent
extraConstruct
méthodes:Enfin, on mélange dans tous les traits dans une plaine modèle, et regardez le résultat:
Nous pouvons définir le contenu initial de
$appends
à l'intérieur de la décorées modèle lui-même, et il remplacera leBaseModel
définition, mais de ne pas interrompre les autres Traits:Toutefois, si vous supprimez le constructeur en même temps que le mélange dans la
AppendingGlue
vous avez besoin de faire un peu de travail supplémentaire, comme discuté dans cette précédente réponse. Il est similaire à l'appelparent::__construct
dans un héritage de la situation, mais vous devez alias le trait du constructeur pour y accéder:Cela peut être évité en héritant d'une classe qui existe au lieu de la
AppendingGlue
trait de caractère, ou utilise d'ores et déjà:Voici un démo en live de toutes qui rassemble.
KISS:
Je ne vois aucune raison pourquoi vous devriez utiliser le trait quand vous êtes tout simplement en ajoutant des attributs.
Je voudrais seulement vous recommandons d'utiliser le trait sans un constructeur comme vous le faisiez, mais seulement si le modèle est en plus très volumineux et que vous souhaitez mincir des choses.
Veuillez noter également que ce n'est pas la bonne façon d'ajouter l'attribut
Vous pourriez faire ceci:
Ajoute les noms d'attribut doit le snake_case de son Nom de la méthode
Édité:
L'idée derrière ajoute est d'ajouter dynamiquement des champs qui n'existent pas dans votre table de base de données pour votre modèle, de sorte que vous pouvez faire comme: