Limit for a relation

I would like to set a limit for a relation, so my $belongsToMany relation can have 4 selected entries at max.

I thought there was something like this:

    public $belongsToMany = [
        'myRelation' => [
            My::class,
            'table' => '...',
            'limit' => 4
        ]
    ];

but it doesnt work and I cant find it in the docu, too.

So I made this workaround within the model:

    public function beforeSave()
    {
        if ($this->myRelation->count() > 4) {
            throw new ValidationException([
                'myRelation' => 'My Error MEssage...'
            ]);
        }
    }

But now I wonder: Am I remembering this wrong and the “limit => 4” never worked or did I miss something?

Hi @LordRazen

You should be able to use a validation rule to enforce this. Specifically the between or size rules should be used. Give it a try!

1 Like

Hm, have to edit my last post, cause this solution did not work as I stated in my first post:

    public $rules = [
        'exampleCreations' => 'between:0,6',
    ];

    public $belongsToMany = [
        'exampleCreations' => [
            Creation::class,
            'table' => 'myplugin_rel_tags_examples',
            'key' => 'tag_id',
            'otherKey' => 'creation_id',
        ]
    ];

(Rules array on the model which have this relation).

As soon as I select one example, the following message appears:
“The example creations field must be between 0 and 6 characters.”

So I wonder why it tells about characters here, the validation rule seem to apply in a strange way.

The second thing: The message should not appear if there’s just one model.

And the third thing: Even if the saving process on the Tag model throws this message, the new relation is already saved. So directly after I selected the entries from the form, configured within the config_relation, the new relation is created.

So… still not sure if I did something wrong or if this is still the wrong spot.

Thanks for your help already. ^^

Hmm, this looks a bug introduced in v3.3. Update october/rain to v3.3.10 and try it again.

1 Like

Thx for having a detailed look.

Just tested it again. I dont see any changes. What’s the expected outcome?

Here is the fix: Fixes countable validation (between, size, etc) · octobercms/library@6e16389 · GitHub

Here is a test confirming it works: Testing validation of relation size · octobercms/test-plugin@ff6a9be · GitHub

1 Like

Ah I think I found our missunderstanding:

I can confirm the rule works if there’s no relation manager configured within config_relation.

I removed my config for the relation manager within the config_relation file and the applied rules worked. Since the relations are created on save of the model this seems reasonable.

If I applied the config_relation again and used the relation manager, the rule still worked on the save of the model and I got the expected error message if two many examples were attached.

But since the relation was created after clicking “Add Selected” within the relation manager modal, the example was already saved.

Do the rules have to be applied differently if a relation manager is used?

This likely occurs because the relation manager uses deferred binding. We will fix it in v3.4 since it involves a bit of internal refactoring.

1 Like

Temporary workaround:

public function beforeValidate()
{
    if ($this->exampleCreations()->withDeferred($this->sessionKey)->count() > 6) {
        throw new ValidationException(['exampleCreations' => 'Too many']);
    }
}
1 Like

Ah ok so there is indeed an issue. I really worried that I did something wrong and now get on your nerves with a bug :smiley:

Thanks for having a second look, the workaround and fixing it ^^