php - hasone - relaciones laravel
Laravel relaciones anidadas (3)
Estoy teniendo muchos problemas para lograr que una relación muy anidada funcione correctamente en la acción.
El comportamiento deseado es el siguiente,
Selecciono un evento por ID y quiero ver qué personas están suscritas. Ahora el problema es que hay algunas tablas entre el evento y la persona ..
Esta es la consulta que funciona!
SELECT persons.id,
persons.firstname,
persons.lastname,
event_scores.score
FROM events
JOIN cities
ON cities.id = events.city_id
JOIN companies
ON cities.id = companies.city_id
JOIN persons
ON companies.id = persons.company_id
JOIN event_scores
ON event_scores.person_id = persons.id
WHERE event_scores.event_id = 1
GROUP BY persons.id
Estas son mis relaciones
Modelo de evento
class Event extends Eloquent
{
protected $table = ''events'';
public function city()
{
return $this->belongsTo(''City'');
}
}
Modelo de ciudad
class City extends Eloquent
{
protected $table = ''cities'';
public function companies()
{
return $this->hasMany(''Company'');
}
public function event()
{
return $this->hasMany(''Event'');
}
}
Modelo de empresa
class Company extends Eloquent {
protected $table = ''companies'';
public function persons()
{
return $this->hasMany(''Person'');
}
public function city()
{
return $this->belongsTo(''City'');
}
}
Modelo de persona
class Person extends Eloquent
{
protected $table = ''persons'';
public function company()
{
return $this->belongsTo(''Company'');
}
public function eventscore()
{
return $this->belongsToMany(''Event'', ''event_scores'', ''person_id'', ''event_id'')
->withPivot(''score'')
->withTimestamps();
}
}
Lo que he intentado
return Event::with(''city'')->with(''company'')->get();
y
return Event::with(''city'')
->whereHas(''companies'', function($query) use ($company_id){
$query->where(''company_id'', $company_id);
})->get();
Y muchas otras posibilidades, estoy realmente atascado en esto. ¿Es tan difícil en la ejecución lograr este tipo de vinculación de relaciones anidadas?
¡Gracias!
Para los campos específicos de la ciudad y las empresas, debe distribuir el con elocuente. P.ej:
return Event::with([
''city'' => function ($query) {
$query->select(''id'', ''...'');
},
''city.companies'' => function ($query) {
$query->select(''id'', ''...'');
},
''city.companies.persons'' => function ($query) {
$query->select(''id'', ''...'');
}
])->get();
HasManyThrough
una relación HasManyThrough
para casos como este: Repositorio en GitHub
Después de la instalación, puedes usarlo así:
class Event extends Model {
use /Staudenmeir/EloquentHasManyDeep/HasRelationships;
public function persons() {
return $this->hasManyDeep(
Person::class,
[City::class, Company::class],
[''id''],
[''city_id'']
);
}
}
Puede obtener atributos de tablas intermedias con withIntermediate()
:
public function persons() {
return $this->hasManyDeep(
Person::class,
[City::class, Company::class],
[''id''],
[''city_id'']
)->withIntermediate(City::class, [''id'', ''...'']);
}
return Event::with(''city.companies.persons'')->get();
Si solo desea seleccionar ciertos campos de la tabla de persons
, use esto:
return Event::with([''city.companies.persons'' => function ($query) {
$query->select(''id'', ''...'');
}])->get();