Search code examples
phpcakephpcakephp-1.3

CakePHP: ID hungriness drives me nuts


For data integrity reasons, I try to populate a ultra simple dropdown 'Countries' in my users/register

As Country and User have no relation (please don't comment on this, there are reasons for it. Cake behaves the same way if Country is a FK), I retrieve the countries in my users_controller as follows, both methods do not prevent Cake from Saving only the country_id:

$this->set('countries', ClassRegistry::init('Country')->find('list'));

$this->set('countries', ClassRegistry::init('Country')->find('list', array('fields' => array('Country.country'))));

The DisplayField is set to: country.

In my register.ctp, the input is set as:

echo $this->Form->input('country');

The countries show nicely in the dropdown. But whatever I try, only the country ID is saved into the users table. I deleted the ID in the table and made country my PK. Cake started talking about 'missing column' Country.id.

How to solve this simple thing or do I have to switch back to simple plain frameworkless PHP where this takes me 30 seconds to settle.

Thanks!


Solution

  • If I understand you correctly, the value and the displayed name of the country should be the same. Cake's find('list') method defaults to id => name lists, which you can customize using the fields parameter (you need to supply two fields). I don't know if this will work if you supply the same field twice, you might want to try that.

    If the convention of the automagic find('list') method doesn't fit your use case, there are infinite ways to create the list yourself. Easiest, use find('list'), then just copy the values to the keys:

    $countries = $this->Country->find('list');
    $countries = array_combine($countries, $countries);
    

    If you have no id field at all in your country table, just use a normal find('all') and build your own array:

    $countries = $this->Country->find('all');
    $countries = array_map(function ($country) { return $country['Country']['name']; }, $countries);
    $countries = array_combine($countries, $countries);
    

    Last but not least, you can forego the Cake Form helper, which expects a value => name array for its options, and output your own country list in raw PHP.

    Cake's conventions are there to safe time for typical patterns. If your patterns are not typical, there's still PHP in CakePHP.