Whats the Yii2 way to relate these models?

I have the following tables: (since I’m not allowed to insert links I attached the file).

I need patient to have both a species and a breed. [size=“2”]What’s the best way to relate these models in Yii2 way? [/size]

[size="2"]I can add two foreign keys to patient but I can lose [/size][size="2"]integrity (i.e. a [/size]patient[size="2"] might end up with a [/size][font="Courier New"][size="2"]dog[/size][/font][size="2"] as species and [/size][font="Courier New"][size="2"]siamese[/size][/font][size="2"] as breed).[/size]

[size=2]

[/size]

[size=2]How would you solve this?[/size]

Create your foeign keys then run crud to auto generate relations.

Add a FKs:

patient to breed

breed to species

you would only need a breed_id field in your patients and it would get the species through the breed model relation.

The patient model should have a relation to breed and the breed model should have a relation to species.

To show the data in the patient model (model would be an instance of patient)

to get the Breed Name


$model->breedRelation->name  

to get the Species Name


$model->breedRelation->speciesRelation->name

Also, I’d recommend changing your varchar elements to char (they are faster and take less space) however, you can only use them for up to 255 characters. Furthermore, if you have one varchar and 10 char in a table MySQL will make the all act like varchar so keep that in mind for other tables.

The last thing is if you plan on having a lot of notes by different people I’d move them to a different table and let each note be it’s own record that way you can record when, who posted the note, when the note was updated and by whom etc.

Lastly, I don’t know what kind of animals your working with but your weight field might need to be looked at.

decimal 3,2 means 9.99 is the highest decimal you can have. So say you wanted to save 10.01 lbs you’d have to have decimal 4,2 for that because the first number is total number of numbers (i.e 4) and the second is how many after the decimal place (i.e. 2).

Wow! Thank you very much for your advice, I’m working on it now. [size=2] [/size]

You’re welcome… I hope you got it working.

Something’s not working. If I add species_id to patient as a FK I can get the patient’s species but then I get all the species’ breeds.

I should note that species and breed are both catalogs, i.e. species contains:

  • Cat

  • Dog

  • Rabbit

While breed contains:

  • Siamese

  • Angora

  • Doberman

  • Pitbull

  • Albino

  • Bevery

(Two breeds per species in this example).

I could make breed_id the FK in patient but this seems counterintuitive for me (I’ll be asking for the breed first and then for the species).

Is there other way to do this?

Make it breed_id then and use the same concept as before. Basically you’d need the breed and you can get the species from the breed.I updated the answer to reflect this.

Thank you for taking the time to answer. Indeed, I don’t see any other to do what I want. Anyway, adding [font=“Courier New”]breed_id[/font] as FK works as expected.

I don’t know if I’m following what you’re trying to do 100%. Do you want to ask for the breed then the species or do you want them to just select breed?

post your new tables as well.

When creating a new [font="Courier New"]patient[/font], I want to:

  1. Select its [font="Courier New"]species[/font]

  2. Select it’s [font=“Courier New”]breed[/font] (based on the selected [font=“Courier New”]species[/font]).

Having a [font=“Courier New”]breed_id[/font] as a FK in [font=“Courier New”]patient[/font] makes the process odd because I’m asking for the [font=“Courier New”]breed[/font] first.

Besides, it’s not [size=2]user friendly because there are a lot of breeds to select from.[/size]

Everything looks good. Just add a dependent dropdown on the form and you should be good to go and have a user friendly selection.

Here is a widget to do it for you or you can make one yourself here is a wiki on how to make one.

The only thing different that you will have to do differently is set a virtual attribute to use for the first dropdown list.

So in your patient model add


/**

* @property string $species

*placeholder for dependent dropdown parent selection

*/

public $species;

and use that for your first dropdown list i.e. on your form




<?php

use yii\helpers\ArrayHelper;

use frontend\models\Species;

;?>


<?= $form->field($model, 'species')->dropDownList(ArrayHelper::map(Species::find()->all(),'id','name'), ['id'=>'species-id']);?>



I’d only use the widget if you are already using kartiks widgets already, otherwise I’d just make it yourself using the wiki. It might even be easier to just make it yourself too.

Thank you very much skworden, that’s exactly what I need!!

did you get this to work?