【问题标题】:Add pivot record and related child records using Laravel使用 Laravel 添加数据透视记录和相关子记录
【发布时间】:2014-09-22 20:46:36
【问题描述】:

我需要帮助在 Laravel 中添加数据透视记录和相关子记录。如果可能的话,我想用 ORM 来做。这里的概念是潜在的捐助者参加筹款活动并进行捐赠,这将由一个或多个指定组成。我的表是这样的(简化):

donor:
  id
  name

fund_raiser:
  id
  date

donation:
  id
  donor_id
  fund_raiser_id
  monetary_type

designation:
  id
  donation_id
  category
  amount

我可以按如下方式手动插入数据透视记录:

// 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);

或者我可以以一种更 ORM 的方式创建数据透视记录:

$fundraiser->donors()->save($donor)

但现在我不知道如何插入指定,因为我不知道刚刚添加的数据透视记录的 id。

【问题讨论】:

  • @deczo。嗯。所以看起来我可能必须定义一个自定义枢轴?我得去研究一下。 Laravel 文档非常少。
  • 仅当您需要预先加载关系时。
  • @deczo。不,我现在不需要急切的加载。也许稍后当我开始提取数据时。现在我正试图弄清楚如何获取数据。如何获取使用 save 方法创建的数据透视表记录的 id,然后我可以在其下添加子记录?我可以使用标准的 Query Builder 调用很容易地插入数据透视记录,但我想知道它们是否可以使用 ORM 来完成。
  • 您将得到所有答案。评论太多了

标签: php laravel orm eloquent


【解决方案1】:

您需要在关系定义上使用withPivot 来获取枢轴id,然后您可以在关系的上下文中访问枢轴模型,从而访问它的id

// Donor model
public function fundRaisers()
{
  return $this->belongsToMany('FundRaiser', 'donation')->withPivot('monetary_type', 'id');
}

FundRaiser 模型上该关系的其他部分也是如此。

那么你可以这样做:

// 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();

现在,为了访问枢轴上的相关Designation 模型,您需要使用hasMany 关系的自定义枢轴模型(扩展Pivot):

use Illuminate\Database\Eloquent\Relations\Pivot;

class DonationPivot extends Pivot {

  protected $table = 'donations';

  public function designations()
  {
    return $this->hasMany('Designation');
  }
}

现在你可以使用它了:

$fundRaiser->pivot->designations;

请注意,您将无法拨打电话

$designation->donation;

使用该设置,因为Pivot 需要在构造时传递依赖项,但是您可以这样做,例如:

$donor = Donor::join('donations', 'donors.id', '=', 'donations.donor_id')->where('donations.id', '=', $designation->donation_id')->first();

要获取数据透视 ID,您可以在当前连接的 PDO 上使用 lastInsertId 的简单方法:

$fundraiser->donors()->save($donor);
$fundraiser->getConnection()->getPdo()->lastInsertId();

【讨论】:

  • 感谢您迄今为止的所有帮助。我想我们正在接近。您提出了一个已经存在数据透视记录的解决方案,但我正在寻找一种涉及创建数据透视记录和相关子记录的解决方案。我已经提出了自己的答案,其中涉及在数据透视记录中手动插入必要的 id 值,但我很好奇是否可以使用更多的 ORM 样式来完成。
  • 如果不为数据透视表创建新模型(扩展 Eloquent,而不是 Pivot)(可以这样做,但使用起来不是很方便),您无法以“更多 ORM”的方式进行操作。检查我编辑的示例 - 最后两行显示,如何获取最后一个 id。
【解决方案2】:

我发现我可以手动插入数据透视记录,如下所示:

// 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);

据我所知,还有另一种创建数据透视记录的方法,它更像是 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)

但是这种方法的问题是我没有得到数据透视记录的句柄,所以我没有办法添加相关记录(指定)。任何能告诉我如何完成第二种方法的人都会得到复选标记。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-07-02
    • 2018-11-14
    • 2019-04-27
    • 2015-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多