简体   繁体   中英

How to save a model with related records in Eloquent ORM from JSON

The Goal

An Eloquent model, Alum , has a many-to-many relationship with School . One alum can have gone to many schools, and one school can have many alums.

Using Eloquent, I can retrieve and output an alum with her schools like this:

$alums = Alum::with('schools')->get();
echo $alums->toJson();

AngularJS then shows the alums in a table. Each row has an edit button that shows a dialog with checkboxes for all the schools the alum could have gone to. Checking a box adds that school to the alum's schools array, and unchecking a box removes it.

So far so good.

The Problem

POSTing or PUTting data back to the server is where things go wrong. The JSON that's sent to the server looks like this:

{
    "id":1,
    "name":"John Doe",
    "schools": [
        {
            "id":1,
            "name":"School A"
        },
        {
            "id":2,
            "name":"School B"
        }
    ]
}

The Alum record saves, but Eloquent doesn't know what to do with the array of schools.

Attempted Solution

From Laravel's documentation on Inserting Related Models in Eloquent , it looks like the way to save related records is to use attach . attach takes an array of IDs, not objects, so I try the following:

// Get the IDs of the schools that this user attended
$schoolIds = [];
foreach ($obj->schools as $school) {
    $schoolIds[] = $school->id;
}

$alum->schools()->attach($schoolIds);
$alum->save();

That works; the alum and his schools are saved to the database. But then there's a new problem: how to detach schools when they're unchecked from an alum's school list. I suppose I could get the IDs of all schools, splice out the ones in the array of checked schools, and pass the result to detach —but I hope there's a more elegant way than that.

What's the best way to save a record and its related records from JSON?

Funny how posting seems to lead you straight to finding a solution on your own. I had missed sync in the Eloquent docs:

The sync method accepts an array of IDs to place on the pivot table. After this operation is complete, only the IDs in the array will be on the intermediate table for the model[.]

After replacing attach with sync, only the checked schools are saved in the alum's school list.

I'm still curious if there's a better way to save related records straight from JSON, though. More input is welcomed.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM