【问题标题】:Laravel 5 retrieve first record within wherepivotLaravel 5 在 wherepivot 中检索第一条记录
【发布时间】:2018-10-26 14:05:56
【问题描述】:

我有 3 张桌子:

*document* [id, core_document]  
*person* [id, name]  
*documentPersonsRole* [document_id, person_id, role] (where role could be accused or victim) 

是否可以创建一个快速的方法来从属于-多的关系中返回第一条记录?这是我的代码,来自模型文件:

public function documentPersonsRole()
{
    return $this->belongsToMany('App\Models\Person', 'document_person_role')
        ->withPivot('role')
        ->withTimestamps();
}

public function accused()
{
    return $this->belongsToMany('App\Models\Person', 'document_person_role')
        ->withPivot('role')
        ->wherePivot('role', 'accused')
        ->withTimestamps();
}

public function victim()
{
    return $this->belongsToMany('App\Models\Person', 'document_person_role')
            ->withPivot('role')
            ->wherePivot('role', 'victim')
            ->withTimestamps();    
}

当我这样称呼时:

App\Models\Document::with('accused')->first()
=> App\Models\Document {#3118
     id: 1,
     core_document: "Iure aut eum aut ex et. Magni aliquam illo voluptatem non repellat. Maxime occaecati reiciendis veniam quod neque reiciendis dolores. Eaque quis molestiae dolorem. Et rerum veniam animi sit beatae inventore voluptas. Aut ea atque nulla quis quam incidunt iusto voluptas. Aut corrupti voluptas minima unde dicta vero aut veritatis. Voluptas vitae nam mollitia quasi porro id quod ut.",         
     accused: Illuminate\Database\Eloquent\Collection {#3127
       all: [
         App\Models\Person {#3139
           id: 41,
           name: "Jamie",               
           pivot: Illuminate\Database\Eloquent\Relations\Pivot {#3138
             document_id: 1,
             person_id: 41,
             role: "accused",
             created_at: "2018-10-24 03:55:23",
             updated_at: "2018-10-24 03:55:23",
           },
         },
       ],
     },
   }

你可以看到 accused 是一个只有一条记录的集合,当我在客户端收到这个时,我必须从数组中提取这条记录,但是我想使用对象。

当我尝试这样的事情时:

public function accused()
    {
        return $this->belongsToMany('App\Models\Person', 'document_person_role')
            ->withPivot('role')
            ->wherePivot('role', 'accused')
            ->withTimestamps()->first();
    }

这是我得到的错误:

带有消息“调用未定义的方法 Illuminate/Database/Query/Builder::addEagerConstraints()”的 BadMethodCallException

如何使用 first() 来检索和反对被告而不是一个记录的数组。

【问题讨论】:

  • 不完全确定,但您是否尝试过belongsToOne 而不是belongsToMany
  • @i-- 我很确定belongsToOne() 不存在
  • ->belongsTo()?

标签: php laravel eloquent


【解决方案1】:

你是如何访问它的?

您可能必须直接调用该方法,而不是让 Laravel 尝试通过魔术方法动态获取它:

$accused = $document->accused()

或者,定义一个accessor

public function getAccusedAttribute() {
    return $this->belongsToMany('App\Models\Person', 'document_person_role')
        ->withPivot('role')
        ->wherePivot('role', 'accused')
        ->withTimestamps()
        ->first();
}

这将允许您使用$accused = $document->accused

通常,当你定义一个返回关系的方法 bar() 时,当你调用 $foo->bar 时,Laravel 会在 PHP 中挂钩 __get() 魔术方法以在幕后某处调用 bar()->get()。由于您已经通过在关系上使用 first() 来运行查询,Laravel 期望一个关系来运行查询,但最终得到了您的模型。

编辑:

如果您仍然想要预先加载关系的能力,这里有另一种方法:

在文档中:

public function accusedPeople()
{
    return $this->belongsToMany('App\Models\Person', 'document_person_role')
        ->withPivot('role')
        ->wherePivot('role', 'accused')
        ->withTimestamps();
}

public function getFirstAccusedAttribute()
{
    return $this->accusedPeople
        ->first();
}

在控制器中:

// If you're eager loading, the relationship to eager load is `accusedPeople`
$document = Document::with('accusedPeople')->first();

// The accused person is accessed with the `first_accused` property
$accused = $document->first_accused;

// if you're returning the model directly for json:
// $document->append('first_accused');

【讨论】:

  • 我确实喜欢这个,但结果证明做错了。 getAccusedAttribute() - 这个函数允许使用它并检索一个关系:$document->accused 谢谢!但是我如何在控制器中使用它而不是这个公共函数 index(Request $request) { $query = Document::with('accused'); $documents = $query->get();返回响应()->json($documents, 200); } 在客户端收到数据后使用:$document->accused
  • @MaximStogniy 抱歉,我不确定您的评论在说什么?
  • 我修正了我的评论,你能帮忙吗?
  • @MaximStogniy 你不能急切地以当前形式加载它(不能使用with('accused')
  • 任何想法如何收集对象文档,其中包括例如 [id, core_document, nucleus(object)] ?或者唯一的选择是一个包含单个元素的数组,需要在客户端转换为一个对象?
【解决方案2】:

试试这个:

App\Models\Document::with(['accused' => function($query){
    $query->first();
}])->first()

这将查询 accused 以仅返回第一行。

【讨论】:

  • 仍然返回一个数组 $vm0.documents[0].accused [{…}, ob: Observer] 0: {…} length: 1 ob: 观察者 {value: Array(1), dep: Dep, vmCount: 0} proto: Array
猜你喜欢
  • 2018-08-31
  • 1970-01-01
  • 2015-09-06
  • 2019-03-16
  • 1970-01-01
  • 2013-11-23
  • 1970-01-01
  • 1970-01-01
  • 2016-02-14
相关资源
最近更新 更多