4

Say I have a record defining a foreign key relationship which is set to required, such as:

public function defineRelations()
{
    return [
        'type' => [
            static::BELONGS_TO,
            'Events_EventTypeRecord',
            'required' => true,
            'onDelete' => static::CASCADE
        ]
    ];
}

If I try to save the record with typeId not set I'll eventually get a database exception but the error won't show up if I call $record->validate().

How do I make a relationship fail validation?

Jamie Pittock
  • 1,511
  • 11
  • 15

2 Answers2

3

Yii/Active Record won't do this by default. You'd need to manually add an exists validation rule to the typeId attribute to get it to behave like you're looking for.

Brad Bell
  • 67,440
  • 6
  • 73
  • 143
  • 1
    Thanks Brad. I have that working now. If I wanted to add the code to this the question to help others, what's the etiquette? Do I update my question or add my own answer? – Jamie Pittock Sep 05 '16 at 10:42
  • @JamiePittock I'd go ahead and request that Brad update his answer to include more details and add your own answer with the example that worked for you. As a reader, I'd vote up the answer with an explicit example and like the separation of question and answer so answers can be voted up independently. – Ben Parizek Sep 05 '16 at 14:31
  • @BenParizek Yeah, on mobile. I can update it when I'm back at a real computer or feel free to add a separate answer Jamie because there's a 90% chance I'll forget, too. – Brad Bell Sep 05 '16 at 15:19
  • Thanks guys. I've posted a separate answer. It was a bit trial and error to figure out but hopefully it'll help the next person looking. – Jamie Pittock Sep 05 '16 at 16:24
2

Thanks to Brad for pointing me in the right direction.

I added this rules method to my record.

public function rules()
{
   $rules = parent::rules();

   $rules[] = [
       'typeId',
       'exist',
       'allowEmpty' => false,
       'attributeName' => 'id',
       'className' => 'Craft\Events_EventTypeRecord',
       'message' => 'You must enter a valid type'
   ];

   return $rules;
}

exist is a shortcut to Yii's built-in CExistValidator validator. The other key => value pairs are properties of that built-in validator.

You could also do it as a separate validator class. Something like:

<?php namespace Craft;

use CExistValidator;

class Events_EventTypeExistValidator extends CExistValidator
{

    public function validateAttribute($object,$attribute)
    {
        $this->message = "You must enter a type";
        $this->allowEmpty = false;
        $this->attributeName = 'id';
        $this->className = 'Craft\Events_EventTypeRecord';

        parent::validateAttribute($object,$attribute);
    }
}

If you did it this way your record's rules method would include:

public function rules()
{
   $rules = parent::rules();

   $rules[] = ['typeId', 'Craft\Events_EventTypeExistValidator'];

   return $rules;
}
Jamie Pittock
  • 1,511
  • 11
  • 15