Laravel Eloquent: Accès aux propriétés et aux noms de table dynamiques

Je suis en utilisant le Framework Laravel et cette question est directement liée à l'utilisation Éloquent dans Laravel.

Je suis en train de faire un Éloquent modèle qui peut être utilisé dans plusieurs tables différentes. La raison pour cela est que j'ai plusieurs tables qui sont essentiellement identiques, mais varient d'une année à l'autre, mais je ne souhaite pas dupliquer le code pour accéder à ces différentes tables.

  • gamedata_2015_nations
  • gamedata_2015_leagues
  • gamedata_2015_teams
  • gamedata_2015_players

Je pourrais bien sûr, ont un grand tableau avec une colonne d'année, mais avec plus de 350 000 lignes de chaque année et de nombreuses années pour faire face à j'ai décidé qu'il serait mieux de les diviser en plusieurs tableaux, plutôt que de 4 énormes tables avec un supplément " où " à chaque demande.

Donc ce que je veux faire est d'avoir une classe pour chaque et faire quelque chose comme ceci à l'intérieur d'une classe de Dépôt:

public static function getTeam($year, $team_id)
    {
        $team = new Team;

        $team->setYear($year);

        return $team->find($team_id);
    }

J'ai utilisé cette discussion sur le Laravel forums pour me faire: http://laravel.io/forum/08-01-2014-defining-models-in-runtime

Pour l'instant j'ai ceci:

class Team extends \Illuminate\Database\Eloquent\Model {

    protected static $year;

    public function setYear($year)
    {
        static::$year= $year;
    }

    public function getTable()
    {
        if(static::$year)
        {
            //Taken from https://github.com/laravel/framework/blob/4.2/src/Illuminate/Database/Eloquent/Model.php#L1875
            $tableName = str_replace('\\', '', snake_case(str_plural(class_basename($this))));

            return 'gamedata_'.static::$year.'_'.$tableName;
        }

        return Parent::getTable();
    }
}

Cela semble fonctionner, cependant, je suis inquiet qu'il ne fonctionne pas dans le droit chemin.

Parce que je suis en utilisant le mot-clé static la propriété $année est conservé au sein de la classe plutôt que de chaque objet, de sorte que chaque fois que je créer un nouvel objet, il détient toujours le $année de la propriété basée sur la dernière fois qu'il a été défini dans un autre objet. Je serais plutôt de l'année a été associée à un objet unique et doit être fixé à chaque fois que je créé un objet.

Maintenant, je suis en train de suivre le chemin que Laravel crée Éloquent modèles, mais vraiment du mal à trouver le bon endroit pour ce faire.

Par exemple, si je le changer à cela:

class Team extends \Illuminate\Database\Eloquent\Model {

    public $year;

    public function setYear($year)
    {
        $this->year = $year;
    }

    public function getTable()
    {
        if($this->year)
        {
            //Taken from https://github.com/laravel/framework/blob/4.2/src/Illuminate/Database/Eloquent/Model.php#L1875
            $tableName = str_replace('\\', '', snake_case(str_plural(class_basename($this))));

            return 'gamedata_'.$this->year.'_'.$tableName;
        }

        return Parent::getTable();
    }
}

Cela fonctionne bien lorsque vous essayez d'obtenir une seule et même Équipe. Cependant, avec les relations qu'elle ne fonctionne pas. C'est ce que j'ai essayé avec les relations:

public function players()
{
    $playerModel = DataRepository::getPlayerModel(static::$year);

    return $this->hasMany($playerModel);
}

//This is in the DataRepository class
public static function getPlayerModel($year)
{
    $model = new Player;

    $model->setYear($year);

    return $model;
}

De nouveau, cela fonctionne très bien si je suis en utilisant statique::$l'année, mais si j'essaie de le modifier pour utiliser $this->année puis ce arrêts de travail.

L'erreur provient du fait que $this->l'année n'est pas définie dans getTable (), de sorte que le parent getTable() la méthode est appelée et le mauvais nom de la table retournée.

Ma prochaine étape est d'essayer et de comprendre pourquoi c'était de travailler avec la propriété statique, mais pas avec le non de la propriété (pas sûr du terme juste pour ça). J'ai supposé qu'il était tout simplement à l'aide de la statique::$année de l'Équipe de la classe en essayant de construire le Joueur relation. Cependant, ce n'est pas le cas. Si j'essaie et la force d'une erreur à quelque chose comme ceci:

public function players()
{
    //Note the hard coded 1800
    //If it was simply using the old static::$year property then I would expect this still to work
    $playerModel = DataRepository::getPlayerModel(1800);

    return $this->hasMany($playerModel);
}

Maintenant ce qui se passe, c'est que je reçois un message d'erreur indiquant gamedata_1800_players n'est pas trouvé. Pas étonnant peut-être. Mais il exclut la possibilité que Éloquent est tout simplement à l'aide de la statique::$ans la propriété de la classe d'Équipe puisqu'il est clairement réglage de la coutume de l'année que j'envoie à la getPlayerModel() la méthode.

Donc maintenant je sais que lorsque l' $l'année est situé au sein d'une relation et est définie de manière statique puis getTable() a accès, mais si c'est le jeu non-statique puis il se perd quelque part et que l'objet ne sait pas à propos de cette propriété par le temps getTable() est appelée.

(note de l'importance de ce travail différent quand il suffit de créer un nouvel objet et lors de l'utilisation de relations)

Je me rends compte que je vous ai donné beaucoup de détail à présent, afin de simplifier et de clarifier ma question:

1) Pourquoi est-static::$année de travail, mais $this->année pas de travail pour les relations, lorsque le travail quand il suffit de créer un nouvel objet.

2) Est-il une manière que je peux utiliser un non statique de la propriété et de réaliser ce que je suis déjà réaliser à l'aide d'une propriété statique?

Justification: La propriété statique de la classe, même après que j'ai fini avec un objet et suis en train de créer un autre objet avec cette classe, ce qui ne semble pas juste.

Exemple:

    //Get a League from the 2015 database
    $leagueQuery = new League;

    $leagueQuery->setYear(2015);

    $league = $leagueQuery->find(11);

    //Get another league
    //EEK! I still think i'm from 2015, even though nobodies told me that!
    $league2 = League::find(12);

Cela peut ne pas être la pire chose dans le monde, et comme je l'ai dit, c'est en fait de travail en utilisant les propriétés statiques sans erreurs critiques. Toutefois, il est dangereux pour l'exemple de code ci-dessus fonctionne de cette façon, donc je voudrais faire correctement et d'éviter un tel danger.

source d'informationauteur robjbrain