Laravel hasMany отношения отделить все

Есть ли простое решение для отсоединения (без удаления) всех связанных моделей через отношение hasMany к модели?

Например, у меня есть две таблицы:

  • Колледж (идентификатор, название)

  • Студент (id, имя, College_id(nullable))

В модели колледжа я определяю эту связь:

class College extends Model
{
    public function students()
    {
        return $this->hasMany('App\Student','college_id','id');
    }
}

Каков наилучший способ отделить всех текущих студентов колледжа от колледжа (т. е. получить всех студентов колледжа и установить для их College_id значение null)?

Есть ли простой способ отделить всех студентов от модели колледжа с помощью красноречия?

Что-то типа

class College extends Model
{
    ...
    public function detachAllStudents()
    {
        ...
    }
}

P.S. уже прочитал этот вопрос Laravel имеет много отсоединений, но получаю ошибки, когда пытаюсь применить его к своему приложению

отсоединить от многих ко многим, я думаю, вам нужно использовать dissociate()

Ahmed Aboud 15.05.2019 20:25

Нет, dissociate() работает только для отношений hasOne.

Jorge Peña 15.05.2019 20:40
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Поиск нового уровня в Laravel с помощью MeiliSearch и Scout
Поиск нового уровня в Laravel с помощью MeiliSearch и Scout
Laravel Scout - это популярный пакет, который предоставляет простой и удобный способ добавить полнотекстовый поиск в ваше приложение Laravel. Он...
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
В последние годы архитектура микросервисов приобрела популярность как способ построения масштабируемых и гибких приложений. Laravel , популярный PHP...
Как построить CRUD-приложение в Laravel
Как построить CRUD-приложение в Laravel
Laravel - это популярный PHP-фреймворк, который позволяет быстро и легко создавать веб-приложения. Одной из наиболее распространенных задач в...
9
2
12 851
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Непосредственно из документации https://laravel.com/docs/5.8/eloquent-relationships:

Переключение ассоциаций

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

$user->roles()->toggle([1, 2, 3]);

Спасибо за ответ, но вызов $this->students()->toggle([1]);; в классе Model вызывает «Вызов неопределенного метода Illuminate\Database\Eloquent\Relations\HasMany::toggle()

Bios90 16.05.2019 00:21

Я думал, что у вас отношение «многие ко многим», потому что вы использовали слово «отсоединиться». Увидел, что Имран успешно ответил на ваш вопрос, уловив эту разницу в терминологии.

Jorge Peña 16.05.2019 20:18
Ответ принят как подходящий

Да, вы можете отсоединить всех студентов колледжа, как показано ниже. На самом деле, у нас уже есть college_id в вашей students таблице, и мы должны каким-то образом сделать это college_id нулевым. В Eloquent это не называется отсоединением. Слово detach приходит, когда у вас есть many to many отношения. Итак, давайте просто обновим студентов и посмотрим, работает это или нет.

$college->students()->update(['college_id' => null);

Итак, ваш метод может быть завершен, как показано ниже:

public function detachAllStudents()
{
    $college->students()->update(['college_id' => null]);
}

Вот и все!

Спасибо за ответ, но вызов $this->students()->detach(); в классе Model вызывает «Вызов неопределенного метода Illuminate\Database\Eloquent\Relations\HasMany::detach()»

Bios90 16.05.2019 00:18

Извините, вы сказали отсоединиться, поэтому я подумал, что это много ко многим отношениям. На самом деле у вас есть отношение один ко многим. В этом случае мы должны использовать метод update(). Я обновил ответ. Пожалуйста, проверьте и посмотрите, работает ли он.

Imran 16.05.2019 05:25

Да, это правильный ответ, наконец-то появилось умное однострочное решение, спасибо!)

Bios90 16.05.2019 13:53

Несмотря на то, что ответ Имрана идеально подходит для этого сценария, я бы добавил более общий подход. Допустим, $college уважает интерфейс, а не реализацию, вы не будете знать внешний ключ во время выполнения.

<?php

use Illuminate\Database\Eloquent\Relations\HasMany;

interface HasStudents {
    public function students(): HasMany;
}

class College extends Model implements HasStudents
{
    public function students(): HasMany;
    {
        return $this->hasMany(Student::class, 'college_id', 'id');
    }
}

function detachStudents(HasStudents $model): void {
    $studentsRelationship = $model->students();
    $studentsRelationship->update([
        $studentsRelationship->getQualifiedForeignKeyName() => null
    ]);
}

detachStudents($college);

Другие вопросы по теме