I just spent a few more hours on this and I still have no idea what to do. I tried setting up a Form Object but don't understand how that's considered a replacement for binding to Eloquent collections, as it's just moving the problem somewhere else while adding extra steps.
Transforming the collection into an array could work but it brings in its share of problems and makes my code way more complicated and less readable, so I'm still not feeling like it's the proper solution.
I'm surprised I can't find any more info on this, but I guess I'll just use the legacy_model_binding config settings for now, even if that's less than ideal. Would love some insight, thank you!
Don't know if it can help but for more context, here's what the view looks like and my component in its original state:
class Plans extends Component {
public $form, $plans;
public $selectedTables = [];
public $plansToDelete = [];
protected $rules = [
'plans.*.title'=> 'required|string|min:3',
'plans.*.order'=> 'required|int',
'plans.*.form_id'=> 'required|int'
];
public function mount() {
// Load the plans with their related tables
$this->plans = $this->form->plans()->with('tables')->get();
// Initialize selectedTables array
foreach ($this->plans as $key=>$plan) {
$this->selectedTables[$key] = $plan->tables->pluck('id')->toArray();
}
}
public function addPlan() {
$last = $this->plans->keys()->last() ?? 0;
// Add the new plan to the collection
$this->plans->add(new Plan([
'order' => $last++,
'form_id' => $this->form->id
]));
$this->selectedTables[$last] = [];
}
public function deletePlan($planId, $key) {
// if plan in the database, stores its id to delete it later
if ($this->plans->get('id', $planId)) {
$this->plansToDelete[] = $planId;
}
// removes the plan from the collection locally
unset($this->plans[$key]);
// removes the selected tables for this plan
unset($this->selectedTables[$key]);
// then reindexes the array
$this->selectedTables = array_values($this->selectedTables);
}
public function submit() {
$this->validate();
// if plans to be deleted
if (!empty($this->plansToDelete)) {
\App\Models\Plan::whereIn('id', $this->plansToDelete)->delete();
// Clear the array
$this->plansToDelete = [];
}
foreach ($this->plans as $key=>$plan) {
$plan->save(); // saving the title
if (isset($this->selectedTables[$key])) {
// Sync the tables for the plan
$plan->tables()->sync($this->selectedTables[$key]);
}
}
}
public function render() {
return view('livewire.options-form.plans');
}
}