winter: create event fail when working with oneToOne or morphOne relationships

Winter CMS Build

1.1

PHP Version

7.4

Database engine

MySQL/MariaDB

Issue description

Hi Everyone, I’m writing a plugin but I’m blocked on a simply one2one relationship.

In one model User, I just want to store :

----------------------------------------------------------------
id | user_unique_id | user_status | create_at | updated_at
----------------------------------------------------------------

Than I want to create different tables to link the user_unique_id for example Anagraphic Model:

----------------------------------------------------------------
id | user_unique_id | name | surname | birthdate | ....
----------------------------------------------------------------

I have so created the two Models

<?php namespace Citrino\Registry\Models;

use Model;
use Citrino\Registry\Models\Anagraphic as Anagraphic;

/**
 * user Model
 */
class User extends Model
{
    use \Winter\Storm\Database\Traits\Validation;

    /**
     * @var string The database table used by the model.
     */
    protected $table = 'wintertest_reserved.citrino_registry_ids';

    /**
     * @var array Relations
     */
    public $hasOne = [
           'anagraphic' => [ Anagraphic::class,'key' => 'user_unique_id', 'otherKey' => 'user_unique_id']
    ];

    protected function beforeCreate(){

        #assign a random user_unique_id
        $this->user_unique_id = random_int(0,12000000);
    }
 
}

And a Anagraphic Model

<?php namespace Citrino\Registry\Models;

use Model;

/**
 * registry Model
 */
class Anagraphic extends Model
{
    use \Winter\Storm\Database\Traits\Validation;

    /**
     * @var string The database table used by the model.
     */
    protected $table = 'wintertest_reserved.citrino_registry_anagraphics';

    /**
     * @var array Relations
     */
    public $belongsTo = [
        'user' => [Citrino\Registry\Models\User::class,
        'key' => 'user_unique_id']
    ];

Now in the user Model fields.yaml

# ===================================
#  Form Field Definitions
# ===================================
tabs:
    fields:
        anagraphic[name]:
            tab: Anagraphic
            label: name
            type: text
            span: storm
            cssClass: col-xs-6
            required: true
        anagraphic[surname]:
            tab: Anagraphic
            label: surname
            type: text
            span: storm
            cssClass: col-xs-6
            required: true
        anagraphic[birthdate]:
            tab: Anagraphic
            label: birthdate
            type: datepicker
            mode: date
            span: storm
            cssClass: col-xs-6
        anagraphic[birthnation]:
            tab: Anagraphic
            label: nation
            type: text
            span: storm
            cssClass: col-xs-3
        anagraphic[birthplace]:
            tab: Anagraphic
            label: city
            type: text
            span: storm
            cssClass: col-xs-3
        active:
            tab: General
            label: Active
            type: checkbox

When creating a new item using a controller Users which point to the model User I got this message error:

"Call to a member function hasRelation() on null" on line 70 of /home/rbi/rbi-he.com/current/public/modules/backend/traits/FormModelSaver.php

I also populated artificially the DB tables citrino_registry_ids and citrino_registry_anagraphics with dummy variable but the same user_unique_id and the system works perfectly and the update event fires without problems.

Steps to replicate

Create a new plugin with two models linked by a simply one To one relationship. Then try to create a new item populating the both model using a field.yaml file:

# ===================================
#  Form Field Definitions
# ===================================
tabs:
    fields:
        anagraphic[name]:
            tab: Anagraphic
            label: name
            type: text
            span: storm
            cssClass: col-xs-6
            required: true
        anagraphic[surname]:
            tab: Anagraphic
            label: surname
            type: text
            span: storm
            cssClass: col-xs-6
            required: true
        anagraphic[birthdate]:
            tab: Anagraphic
            label: birthdate
            type: datepicker
            mode: date
            span: storm
            cssClass: col-xs-6
        anagraphic[birthnation]:
            tab: Anagraphic
            label: nation
            type: text
            span: storm
            cssClass: col-xs-3
        anagraphic[birthplace]:
            tab: Anagraphic
            label: city
            type: text
            span: storm
            cssClass: col-xs-3
        active:
            tab: General
            label: Active
            type: checkbox

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Comments: 19 (14 by maintainers)

Commits related to this issue

Most upvoted comments

Final solution

if ($isNested && is_array($value)) {
    // Handle related records that don't exist yet
    if (!$model->{$attribute} && $model->hasRelation($attribute)) {
        $model->{$attribute} = $model->{$attribute}()->getRelated();
    }
    $this->setModelAttributes($model->{$attribute}, $value);
}