1

I want to have a polymorphic relation between services and different types of service data (In this example its typo3_data).

I have the following data model:

projects
--------
id
name

services
--------
id
type
project_id
data_type
data_id

typo3_data
--------
id
url

The projects and services have a simple OneToMany Relation. But the service model needs a polymorphic relation because there are different kinds of services which needs different columns in there respective table.

My Service Model looks like this:

class Service extends Model
{
    public function project()
    {
        return $this->belongsTo(Project::class);
    }

    public function data()
    {
        return $this->morphTo('data');
    }
}

The TYPO3Data Model looks like this:

class TYPO3Data extends Model
{
    protected $table = 'typo3_data';

    public function service()
    {
        return $this->morphOne(Service::class, 'data');
    }
}

Currently I try to save the data on the service this way(simplified):

public function store(Project $project)
{
    $service = new Service(['type' => 'TYPO3']);
    $service->data()->save(new TYPO3Data(['url' => 'http://example.com']));
    $project->services()->save($service);
}

But now I get an error with a NOT NULL constraint on services.data_type.

Does anyone know how to solve this part, that I can save the polymorphic relation?

Thanks in advance

1 Answer 1

4

save() is meant for HasMany relationships. Use associate() instead:

$data = TYPO3Data::create(['url' => 'http://example.com']);
$service = new Service(['type' => 'TYPO3']);
$service->data()->associate($data);
$project->services()->save($service);

Also, take a look at many-to-many polymorphic relationships.

Sign up to request clarification or add additional context in comments.

3 Comments

I tried this and I got the exact same error with either save or associate
@SpencerWilliams Please open a new question.
Thanks @JonasStaudenmeir , It worked. BTW, Your "Has Many Deep" package is awesome too. Thank you!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.