5

It seems like there is no sync() function for morph tables on Laravel.

I have two tables avails and questions. questions is a morphMany table. I want to use the sync command, and this is what I did:

Avail::find($id)->questions()->sync($some_ids);

This gives me the following error:

Call to undefined method Illuminate\Database\Query\Builder::sync()

So is there a way to get sync to work or am I just not doing this right?

Kousha
  • 32,871
  • 51
  • 172
  • 296

1 Answers1

5

morphMany is a 1-to-many, not many-to-many relation, so there is no sync method.

Use saveMany/save instead, and associate for the other way around.


to mimic sync behaviour for this kind of relation you can do this:

$questionsOld = $avail->questions()->get();

$questionsOld->each(function ($question) {
  // appropriate fields here:
  // 1*
  $question->FOREIGN_ID = null;
  $question->FOREIGN_TYPE = null;
  $question->save();
});

$questionsNew = Question::whereIn('id', $someIds)->get();

// *2
$avail->questions()->saveMany($questionsNew->getDictionary());

Now:

*1 you can't use dissociate and must explicitly set relation_id and relation_type to null, since morphTo doesn't override this method, so it wouldn't work as expected.

*2 getDictionary() returns simple array of models, instead of collection. It's required becase saveMany typehints its parameter as array.

Jarek Tkaczyk
  • 78,987
  • 25
  • 159
  • 157
  • Makes sense. So I have a list of `questions`. When I update them, I want to basically sync the question ids. There may be new questions, removed questions, or simply updated questions. How would I go about syncing them without sync? I could just get the list of ids, and compare them with the old ids and then manually remove/add/update – Kousha Sep 22 '14 at 18:39