Отношения Laravel и использование метода push()

Я пытаюсь найти другой подход к сохранению/обновлению данной модели и ее отношений в базе данных.

В основном у меня есть форма для страницы «Автор», где можно добавить несколько «Книг». Естественно, модели «Автор» и «Книга» имеют отношение «один ко многим».

Согласно официальному руководству laravel, вам необходимо:

  1. Добавьте все входные данные в модель «Автор».
  2. Создайте и сохраните модель «Автор» в БД
  3. Для каждой "Книги" входных данных
  4. Создайте и сохраните каждую модель «Книги» в БД, используя $author->books()->save($book);

Laravel также заявляет, что "Иногда вам может понадобиться сохранить не только модель, но и все его отношения. Для этого вы можете использовать метод push: $user->push();".

Но я не смог найти ни одного учебника о том, как заполнить модель «Автор» отношениями «Книга» и фактически использовать метод push().

Я ищу что-то вроде этого:

$author = new Author();
$author->name = "Bill Jobs";
$author->phone = "555 - 123456";

// fill model with relations

$author->addRelation($relationsArray)

if($author->push())
{ 
   // ....
}

Также то же самое должно работать для обновления «Автор»: сначала удалите уже сохраненные отношения, а затем сохраните новые.


person Tudor Ravoiu    schedule 05.12.2014    source источник


Ответы (3)


тлдр; Ниже вы найдете push описание, а также разницу между createMany и saveMany методами отношений.

Eloqeunt не обрабатывает отложенные отношения (например, Doctrine2), т.е. вы не можете сделать это:

$author = new Author;
$book = new Book;
$book->author()->associate($author);
$author->push();

Потому что ассоциация выполняется именно тогда, когда вы вызываете метод associate. И все, что он делает, это:

$child->foreign_key = $parent->primary_key;

Таким образом, в приведенной выше ситуации primary_key равно null, потому что $author еще не сохранено.


Далее, хотя в документах не говорится, что push создает ассоциации, это может произвести такое впечатление, и может возникнуть соблазн сделать это:

$author = Author::first(); // existing parent
$books = Book::get(); // existing children collection

$author->books = $books;
$author->push();

Однако это тоже не сработает. Во-первых, Eloquent не позволяет вам явно назначать отношение, как указано выше, тогда, даже если вы сделаете это правильно, ассоциация все равно не будет создана:

$author = Author::first();
$books = Book::get(); 

$author->setRelation('books', $books);
$author->push();

На этот раз отношение было назначено правильно, но ассоциация (назначение внешних ключей) не была выполнена. Таким образом, несмотря на то, что и author, и все books будут сохранены/обновлены, они вообще не будут связаны.


При этом вам либо нужно связать модели самостоятельно и использовать push ИЛИ использовать методы Eloquent (createMany / saveMany):

Начните с:

$author = Author::find($someId);
// delete existing books
$author->books()->delete();

1, затем вручную:

// for example:
$booksInput = Input::get('books');
  // validate etc
foreach ($booksInput as $bookArray)
{
  $book = new Book;
  // assign the value from, eg.
  $book->fill($bookArray);
  $book->author()->associate($author);
  // or set FK explicitly
  $book->author_id = $author->getKey();

  // add to the author's collection
  $author->books->add($book);
}

$author->push(); // saves author and each of the books in separate queries

2 или createMany:

$booksAsArrays = Input::get('books'); // array of arrays
// validation
$author->books()->createMany($booksAsArrays); // associate and save each book

3 или saveMany:

$booksAsModels = []; // array of Book models
$booksAsArrays = Input::get('books'); // array of arrays
// validation

foreach ($booksAsArrays as $bookArray)
{
  $booksAsModels[] = new Book($bookArray);
}
$author->books()->saveMany($booksAsModels); // associate and save each book
person Jarek Tkaczyk    schedule 05.12.2014

Для создания многих:

$author->books()->createMany($relationsArray);

Сначала удалите уже сохраненные отношения, затем сохраните новые

потом

$author->books()->delete(); // or if you are using soft delete forceDelete()
$author->books()->createMany($relationsArray);
person xAoc    schedule 05.12.2014

вы можете обновить свою книгу и модель автора, используя метод push.

$book = Book::first();
$book->author->author_name = "Mark Twin";
$book->book_name = "Life On The Mississippi";
$book->push();

вот ссылка для деталей [1]: https://medium.com/@JinoAntony/10-hidden-laravel-eloquent-features-you-may-not-know-efc8ccc58d9e

person Waleed    schedule 22.07.2020