Agregue registros dinámicos y registros secundarios relacionados usando Laravel
Pregunta
Necesito ayuda para agregar un registro dinámico y registros secundarios relacionados en Laravel.Me gustaría hacerlo usando ORM si es posible.El concepto aquí es que los donantes potenciales asisten a eventos para recaudar fondos y hacen donaciones, que estarán compuestas por una o más designaciones.Mis tablas son así (simplificadas):
donor:
id
name
fund_raiser:
id
date
donation:
id
donor_id
fund_raiser_id
monetary_type
designation:
id
donation_id
category
amount
Puedo insertar el registro dinámico manualmente de la siguiente manera:
// assume both donor and rundraiser records already exist
$donor = Donor::find($donorID);
$fundraiser = FundRaiser::find($fundraiserID);
// create the pivot record
$donation = Donation::create(['donor_id' => $donor->id, 'fundraiser_id' => $fundraiser->id, 'date' => 'somedate']);
// now add a designation
$designation = new Designation(['Category' => 'General', 'Amount' => '100']);
$donation->designations()->save($designation);
O puedo crear el registro dinámico de una manera más ORM:
$fundraiser->donors()->save($donor)
Pero ahora no sé cómo insertar la designación, ya que no sé la identificación del registro dinámico que se acaba de agregar.
Solución
Necesitas withPivot
en las definiciones de relación para obtener el pivote id
, entonces puede acceder al modelo pivote, por lo que es id
, en el contexto de la relación:
// Donor model
public function fundRaisers()
{
return $this->belongsToMany('FundRaiser', 'donation')->withPivot('monetary_type', 'id');
}
Lo mismo ocurre con la otra parte de esa relación en el FundRaiser
modelo.
Entonces puedes hacer esto:
// let's grab single donor
$donor = Donor::first();
// then load fund raisers and get one of them
$fundRaiser = $donor->fundRaisers->find($someId);
// now we're in the context of the relation, so we can access pivot model
$donationId = $fundRaiser->pivot->id;
// use it to save designation
$designation = new Designation([ SOME VALUES]);
$designation->donation_id = $donationId;
$designation->save();
Ahora, para acceder a temas relacionados Designation
modelos en el pivote, necesita un modelo de pivote personalizado (extendiendo Pivot
) con hasMany
relación:
use Illuminate\Database\Eloquent\Relations\Pivot;
class DonationPivot extends Pivot {
protected $table = 'donations';
public function designations()
{
return $this->hasMany('Designation');
}
}
Ahora puedes usarlo:
$fundRaiser->pivot->designations;
Ten en cuenta que no podrás llamar
$designation->donation;
con esa configuración, porque Pivot
requiere que las dependencias se pasen durante la construcción; sin embargo, puedes hacer esto, por ejemplo:
$donor = Donor::join('donations', 'donors.id', '=', 'donations.donor_id')->where('donations.id', '=', $designation->donation_id')->first();
Para obtener la identificación del pivote de manera fácil, puede usar lastInsertId en el PDO de la conexión actual:
$fundraiser->donors()->save($donor);
$fundraiser->getConnection()->getPdo()->lastInsertId();
Otros consejos
He encontrado que puedo insertar el registro de pivote manualmente de la siguiente manera:
// assume both donor and rundraiser records already exist
$donor = Donor::find($donorID);
$fundraiser = FundRaiser::find($fundraiserID);
// create the pivot record, plugging in the necessary id values manually
$donation = Donation::create(['donor_id' => $donor->id, 'fundraiser_id' => $fundraiser->id, 'date' => 'somedate']);
// now add a designation
$designation = new Designation(['Category' => 'General', 'Amount' => '100']);
$donation->designations()->save($designation);
Hay otra forma de crear el registro de pivote que conozco, que es más estilo de ORM:
// assume both donor and rundraiser records already exist
$donor = Donor::find($donorID);
$fundraiser = FundRaiser::find($fundraiserID);
// create the pivot record
$fundraiser->donors()->save($donor)
Pero el problema con este método es que no obtengo un asa al registro de pivote, por lo que no tengo forma de agregar registros relacionados (designaciones).Cualquier persona que pueda mostrarme cómo completar el segundo método obtendrá la marca de verificación.