Laravel Eloquent 'with' возвращает ноль, но ссылка на отношение на самом объекте возвращает правильное значение - PullRequest
0 голосов
/ 14 апреля 2020

Буду признателен за помощь в понимании несоответствия, которое я вижу в моем проекте laravel 6.8:

У меня есть модель "UserAlert"

class UserAlert extends Model
{
    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'user_id', 'from_id', 'subject', 'message'
    ];

    //Relationships
    public function user()
    {
        return $this->belongsTo(User::class);
    }

    //Only include the name of the sender in this relationship
    public function from()
    {
        return $this->hasOne(User::class, 'id', 'from_id')->select('name');
    }
}

Отношение «пользователь» по умолчанию представляет собой «user_id» для «id» и работает как ожидалось.

Как вы можете видеть, отношение «from» извлекает имя из модели User, связанной с «from_id» из UserAlert.

Если я получу коллекцию UserAlerts и затем проведу по ней итерацию, чтобы получить отношение «от» для каждого из них следующим образом:

$thisUserAlerts = \App\UserAlert::where('user_id', $thisUser->id)->get();
foreach ($thisUserAlerts as $userAlert) {
    dump($userAlert->from);
}

Затем я увижу имя из Отношение «from», как я желаю:

...
#original: array:1 [
    "name" => "Administrator"
  ]
...

Однако, если я пытаюсь включить отношение непосредственно в коллекцию UserAlert, используя «with», то from »всегда будет нулевым.

$thisUserAlertsWith = \App\UserAlert::where('user_id', $thisUser->id)->with('from')->get();
dump($thisUserAlertsWith);
...
#relations: array:1 [
        "from" => null
      ]
...

Я вижу из журнала запросов, что когда я делаю вышеизложенное, нет запроса sql для извлечения имени из таблицы пользователей, но когда я перебираю коллекцию и вызываю '-> from' напрямую, тогда запрос сделан.

есть Я неправильно понял «с»?

[отредактировано для устранения расхождений в примерах для ясности]

1 Ответ

0 голосов
/ 14 апреля 2020

Благодаря Даниалу Петровалиеву за то, что он указал мне правильное направление, я нашел два ответа на мою проблему.

Для включения отношений выясняется, что вы должны включить первичный ключ (id) в коллекция.

Таким образом, первый ответ - изменить отношение с

return $this->hasOne(User::class, 'id', 'from_id')->select('name');

на

return $this->hasOne(User::class, 'id', 'from_id')->select(['id', 'name']);

Тогда мой оригинальный пример работает так, как я планировал.

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

Поэтому полностью удалите select из взаимосвязи:

return $this->hasOne(User::class, 'id', 'from_id')

и вместо этого отфильтруйте коллекцию следующим образом:

$userAlerts =  UserAlert::where('user_id', $id)->with('from:id,name')->get();

Снова необходимо включить первичный ключ (id) для его работы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...