J'utilise un tableau croisé dynamique sur le projet avec lequel je travaille pour obtenir les travaux des utilisateurs.
Par exemple: User::find(1)->works
me donne les travaux de l'utilisateur avec l'ID de 1.
Le fait est que je veux filtrer ces résultats avec des données Pivot supplémentaires.
Quelque chose comme:
User::find(1)->works->pivot->where('active',1)->get();
Dans lequel l'actif est la colonne que j'ai définie dans mon tableau croisé dynamique user_works.
Ceci est ma partie connexe de mon modèle User.php:
<?php
class User extends Cartalyst\Sentry\Users\Eloquent\User {
public function works() {
return $this->belongsToMany('Work','user_works')->withPivot('active')->withTimestamps();
}
}
Ceci est ma partie connexe de mon modèle Work.php:
<?php
class Work extends Eloquent {
public function users() {
return $this->belongsToMany('User','user_works')->withPivot('active')->withTimestamps();
}
}
Voici mon schéma de tableau croisé dynamique:
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
class CreateUserWorksTable extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('user_works', function(Blueprint $table) {
$table->increments('id');
$table->integer('user_id')->unsigned()->default(0);
$table->integer('work_id')->unsigned()->default(0);
$table->enum('active',array('0','1'))->default(1);
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
$table->foreign('work_id')->references('id')->on('works')->onDelete('cascade');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::drop('user_works');
}
}
Existe-t-il un moyen d'obtenir les données sans créer un nouveau modèle pour le tableau croisé dynamique?
Merci d'avance,
Edit: Je peux filtrer de cette façon:
return User::find(1)->works()->where('user_works.active','=','1')->get();
J'ai dû taper le nom de la table brut. Mais existe-t-il une meilleure façon de gagner cela sans l'utiliser?
Laravel 4.1 apporte natif wherePivot
et orWherePivot
méthodes , ce qui est directement une solution à mon problème.
Chaque fois que vous appelez withPivot('foo')
, Laravel vous faites:
SELECT ... `table`.`foo` AS `pivot_foo` FROM `table` ...
MySQL en particulier permet l'utilisation d'alias de colonnes sur HAVING
, GROUP BY
et ORDER BY
clauses, mais pas sur WHERE
clauses.
HAVING
et WHERE
sont utilisés pour filtrer les requêtes, mais ils se comportent légèrement différemment: HAVING
est appliqué après GROUP BY
et WHERE
est avant.
En règle générale, vous ne devez pas utiliser d'alias de colonne (pivot_foo
dans ce cas) pour le regroupement, le filtrage ou quelque chose du genre, car il peut ne pas fonctionner avec d'autres bases de données SQL.
Bien que non recommandé, il est possible d'utiliser:
return User::find(1)->works()->having('pivot_active','=','1')->get();
J'essaie de configurer toutes les relations dans les deux sens car cela permet d'utiliser des propriétés dynamiques, par exemple $user->works()
.
class Collection extends Eloquent {
public function contents()
{
return $this->belongsToMany('Content', 'collection_content', 'collection_id', 'content_id')->withPivot('collection_id', 'group_id', 'field_identifier');
}
}
class Content extends Eloquent {
public function collections()
{
return $this->belongsToMany('Collection', 'collection_content', 'collection_id', 'content_id')->withPivot('collection_id', 'group_id', 'field_identifier');
}
}
class CollectionContent extends Eloquent {
public function content()
{
return $this->belongsTo('Content');
}
public function collection()
{
return $this->belongsTo('Collection');
}
}
Ensuite, interrogez:
$works = User::find(1)->works()->where('active', 1)->get();
La documentation d'Eloquent est horrible en ce qui concerne l'utilisation des tableaux croisés dynamiques. Ceci est un excellent tutoriel: http://www.developed.be/2013/08/30/laravel-4-pivot-table-example-attach-and-detach/