Select Existing Relationship OR Create New Related Record

I’m new to Yii, so please forgive any fundamental lack of understanding I might have.

Using a single form, I want to be able to:

a] Select an existing relationship (by primary key)

OR

b] Create a new related record

…with both models being properly validated and saved easily.

For example, if I have a form to create an ‘item’ and items can have a ‘type’, I want to be able to select an existing type OR create a new type on the fly within the same form.

I have followed the Wiki on working with multiple models as a start:

http://www.yiiframework.com/wiki/19/how-to-use-a-single-form-to-collect-data-for-two-or-more-models/

But if I select an existing ‘type’ (by dropdownlist), then validation for the type model fails because no new type name is provided (by textfield) for the type model. If I enter a new ‘type’, then validation for ‘item’ fails because no typeid is provided for the item model.

My hack was to set type name = ‘placeholder’ or typeid = -1 simply to pass validation for each scenario. Then to save the user input, I had to write quite a bit of code to determine if each of these inputs were new or existing and handle the database interaction accordingly.

I felt like what I was doing was terrible practice and a lot of work for what seems to be a fairly common situation. Does anyone have a clean/simple/elegant best-practice approach for allowing EITHER [select an existing related record] OR [create a new related record] that validates and saves nicely?

Thanks so much.

in your model you can check if you are inserting a new record with


if($this->isNewRecord)

What is your validation rule for the drop down and what are the options for the drop down?

Thanks for your reply, bettor.

Suppose a simple table structure like this:


type

----

id*

name*


item

----

id*

typeid*

name*

And a form like this:

2447

simpleform.gif

So validation rules for both the type and item models are straight from Gii, everything is required.

The dropdown list is populated with CHtml::listData(Type::model()->findAll(), ‘id’, ‘name’).

How do I use out-of-the-box validation and save of both the Type model and the Item model, while giving the user both options: [select an existing type from dropdown] OR [enter a new type into the textfield]?

I may even be approaching this wrong from a UI perspective. But basically, to reiterate what I’m trying to do, I want to provide the option of specifying an existing relationship OR creating a new related record on the same form.

Thanks for any advice.

you will need to apply some logic to check if new type has been selected from drop down and if so read the property from the text box. What happens when you select an existing one? Do all existing ones show up somewhere in the form?

When I select an existing type from the dropdownlist, then the Item model validates ok, but the Type model does not validate (because the textfield is bound to type.name which is a required field). Conversely, if I enter a new type in the textfield, then Type model validates ok, but the Item model fails validation because the dropdownlist is bound item.typeid which is empty.

Yes, that’s no problem. But it’s sounding like there isn’t a well established, best-practice, out-of-box way to do this. I had to ‘hack’ my way around the validation (as explained in the first post), then I had to do what I thought was quite a bit of coding to check all the various scenarios (I have multiple instances of this on the same form). It didn’t seem right, and I thought there must be a major gap in my understanding. I might post my code tonight and maybe someone can tell if I’m doing something that’s terrible practice.

Would a ‘combobox’ approach work?

I think you are trying to essentially have a ‘dynamic’ type list, right? You don’t want to be bound to pre-exisiting choice but have the ability to add them on the fly?

I have a similar situation with users and roles (not RBAC roles, more like titles). I need to define titles on the fly as well as present the existing list. I am using the combobox extension successfully.

you will definitely need to alter your validation rules to achieve what you want. Better yet with custom validation class.