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?


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) {
            $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;
            $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