Updating the text of a one to many relationship (backend)?

Thanks for taking the time to consider helping on this, and I hope it turns into something that will help many others.
(Extremely brief summary: A task has many steps. A step has 1 title. Title’s must be unique so have many steps)

I have a model called Step with a field called title_id
A model called StepTitle with a field called title

For the life of me I cannot figure out how to simply update it as a text field. If I use a relation, it forces a drop down on me, but at least the title displays. If I use a text box, the best I can get is the title ID but not the title itself. I was able to understand this watch and learn link (below) so am able to ‘Create’ new titles straight from the dropdown. The idea is to create a step from tasks directly which works fine.

In the case of update however, I don’t want to create a new title, I want to alter the title in case of a typo. How do you guys update the text of a one to many relationship?

Thanks!

Alright, I am officially replying to myself for anybody in the future. I hope someone more experienced can explain a better way, but for now here’s what I have done:

First in Plugin.php, I am altering a form field not actually extending them:

    public function boot(){
        Steps::extendFormFields(function ($form, $model, $context) {
            if (!$model instanceof Step) {
                return;
            }
            $form->data->title_id = $form->model->title->title;//This ensures text shows up in the text input field rather than the ID
        });
    }

Because there are multiple ways to create (see video above), they need to be accounted for so it is able to create directly from the backend form, or from a dropdown as explained above

    public function beforeCreate(){
        if(!isset($this->title->title))//When creating a step the backend form, title->title won't exist so set $title to $title_id which has the text
            $title = $this->title_id;
        else
            $title = $this->title->title;//When creating from a Select2 dropdown, it exists

        $title_id = StepTitle::firstOrCreate(['title' => $title])->id;//If the title doesn't already exist, create it
//Now that we have an official Title, set the related ID
        $this->title_id = $title_id;
    }

In my Step.php model file, update must operate much differently than create so this allows us to manipulate as needed

    public function beforeUpdate(){
        //Get the StepTitle Model using the original ID, and update it to whatever may have changed in the text field
        StepTitle::where('id', $this->original['title_id'])->update(['title' => $this->title_id]);
        //Set the ID back to its original related value now that the text field has been updated
        $this->title_id = $this->original['title_id'];
    }

And that’s all that was needed

1 Like