Search code examples
laravelormoctobercmsoctobercms-plugins

OctoberCMS Rainlab.Builder- Error on "hasOne" relation to same model


I'm developing an October CMS Plugin for managing animals (with rainlab.builder). Animals have a couple of fields and relations. Every animal have a father and a mother animal. But when I try to safe my animal the following error appears:

Event Log:

PDOException: SQLSTATE[23000]: Integrity constraint violation: 1048
Column 'id' cannot be null in dir/website/vendor/laravel/framework/src/
Illuminate/Database/Connection.php:413

Plugin animal form:

SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'id'
cannot be null (SQL: update `prefix_animals_animal` set `id` =  where
`prefix_animals_animal`.`id` = 1 and `prefix_animals_animal`.`id` is 
not null)" on line 666 of dir/website/vendor/laravel/framework/
src/Illuminate/Database/Connection.php

The error only appers when I use the relations (child -> father, child -> mother).


Code

I have implemented the following hasOne - relations to my animal model:

/* Relation */

public $hasOne = [
    'father' => [
        'Namespace\Animals\Models\Animal',
        'key' => 'id',
        'otherKey' => 'id'
    ],
    'mother' => [
        'Namespace\Animals\Models\Animal',
        'key' => 'id',
        'otherKey' => 'id'
    ]
];

This are my fields from field.yaml:

father:
    label: Father
    oc.commentPosition: ''
    nameFrom: name
    descriptionFrom: description
    emptyOption: 'No father'
    span: left
    type: relation
mother:
    label: Mother
    span: right
    oc.commentPosition: ''
    nameFrom: name
    descriptionFrom: description
    emptyOption: 'No mother'
    type: relation

I would be very happy if someone have a solution for these kind of relations. Cheerio!


Solution

  • Don't use id as the primary key for the relation as this is not good practice.

    Actually this creates the problem you are seeing also. Currently your model is using the id for primary Id, mother Id and father Id. You can't do that.

    Add mother_id and father_id to the Animal model and change the relation definition to this:

    public $hasOne = [
        'father' => [
            'Namespace\Animals\Models\Animal',
            'key' => 'father_id',
            'otherKey' => 'id'
        ],
        'mother' => [
            'Namespace\Animals\Models\Animal',
            'key' => 'mother_id',
            'otherKey' => 'id'
        ]
    ];
    

    PS. In your case you dont have to define key and otherKey as the default value for otherKey is "id" and the otherKey value is created from the relation name with the "_id" suffix.