Laravel 5 получить первую запись в рамках wherepivot - PullRequest
0 голосов
/ 26 октября 2018

У меня есть 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",
           },
         },
       ],
     },
   }

И вы можете видеть, что обвиняется это коллекция только с одной записью, и когда я получаю ее на стороне клиента, я должен извлечь эту запись из массива, но я хочу работать с объектом.

Когда я пытаюсь что-то вроде этого:

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

Это ошибка, которую я получаю:

BadMethodCallException с сообщением 'Вызов неопределенного метода Illuminate / Database / Query/ Builder :: addEagerConstraints () '

Как я могу использовать first () для извлечения и опроса объекта обвиняемого вместо массива с одной записью.

Ответы [ 2 ]

0 голосов
/ 26 октября 2018

попробуйте это:

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

это запросит accused, чтобы вернуть только 1-ую строку.

0 голосов
/ 26 октября 2018

Как вы к нему обращаетесь?

Возможно, вам придется вызывать метод напрямую, вместо того, чтобы позволить Laravel попытаться динамически получить его с помощью магического метода:

$accused = $document->accused()

Или определить средство доступа :

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 подключит магический метод __get() в PHP, чтобы вызвать 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');
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...