Optional required model fields.


I faced some scenario that needs a lot of spare coding.

Imagine you have a signup formhaving 3 mandatory fields:

  • username

  • password

  • password_repeat

However, customer says he may optionally need the following:

  • Full name

  • Agreement checkbox

  • Captcha

My question is: what is the best practice to achieve this in

less code? It’s obvious this should be bound to a model. Most

likely, a behavior.

Common functionality for $useCaptcha = true; controller’s property

would be:

  • prevent validation, see CModel::validate($attributes)

  • prevent attribute assignment even if it’s safe

  • prevent form field rendering in a view

This is what I have in a code right now. It’s not clean and is spread

over controller / views (this is actually a controller’s action):

            // Populate a list of attributes to validate.

            $attributes = array_flip($form->getSafeAttributeNames());


            // ... and exclude hidden attributes.

            if (!$this->useName) unset($attributes['name'], $data['name']);

            if (!$this->useAgreement) unset($attributes['agreement'], $data['agreement']);

            if (!$this->useCaptcha) unset($attributes['captcha'], $data['captcha']);


            // Set form data.


            if ($form->validate(array_keys($attributes)) {...}

Thanks in advance for your feedback! :)

Hi waylex,

it seems like a typical case for using model scenario.



Well, this might be done if we could apply multiple scenarios to the model.

Otherwise (in this particular case) we need to create 7 different scenarios

for all property combinations:








Then we’ll need to write code for genearting these scenario names from 3 props:

$useName, $useAgreement, $useCaptcha. This is not the way thiings should work :)

And still we need controller’s property to use it in a view. I start to think of

an additional CModel method: setUnsafeAttributes(). It should override rules()

attribute safety rules and would do the job! In a view we could do the following:

if ($model->isAttributeSafe('captcha')) {

// Render our captcha field...


I think this should become a ticket! :)