0

I'm using Associations to Link Models together in CakePHP.

I have a Player model that is linked to a Statistic model using a $hasMany relationship. So basically one player can have many statistics.

After I set up these relationships, I use cake bake to generate the controllers and views for both the Player and Statistic models.

Everything works fine and works as expected, but when I go to add a statistic using the add template, the player_id is used as the association.

My question is how do I set up the model to use the player_id as the association but use something like the player's first and last name as the drop down menu in the add template.

Currently if I go to add a new statistic, I get a drop down box that called "Player" that lists all of the player id's but what I want is for the player's first_name and last_name to be in that drop down box instead of the id. I realize that I can modify the controller or template to accomplish this, but I Want to know if I can do this while setting up the model so that cake bake can take care of it.

Player Model:

<?php
class Player extends AppModel {
    public $name = 'Player';
    public $belongsTo = array(
        'School' => array(
            'className'    => 'School',
            'foreignKey'   => 'school_id'
        )
    );
    public $hasMany = 'Statistic';
}

Statistic Model:

<?php
class Statistic extends AppModel {
    public $name = 'Statistic';
    public $belongsTo = array(
        'Player' => array(
            'className'    => 'Player',
            'foreignKey'   => 'player_id'
        )
    );
}

Players Table

`id|school_id|first_name|last_name|number|position
tereško
  • 58,060
  • 25
  • 98
  • 150
bigmike7801
  • 3,908
  • 9
  • 49
  • 77

1 Answers1

2

Cake uses the model's displayField attribute when choosing the default columns for a list. If none is defined for the model it will look for name or title. So in your model you can use:

public $displayField = 'first_name';

This will display the player's first name in the list.

If you want the display field to be the concatenation of two fields, you can use a virtual field in the model like so:

public $virtualFields = array(
    'name' => "TRIM(CONCAT(Player.first_name, ' ', Player.last_name))"
);

Note the above works for Mysql. For another kind of database you will need to adjust the syntax. For example, for Sqlite it would be:

 TRIM(Player.first_name || ' ' || Player.last_name)

Then add in your model:

public $displayField = 'name';
Doug Owings
  • 4,438
  • 1
  • 21
  • 21
  • I added ` public $virtualFields = array( 'name' => "TRIM(CONCAT(Player.first_name, ' ', Player.last_name))" );` above and below the `public $belongsTo = array()` in the `Statistic` model, then regenerated the models and views using cake bake but nothing changed. Did I add this to the wrong section? – bigmike7801 Jul 26 '12 at 22:18
  • @bigmike7801 The virtual field should be in the `Player` model. I don't think you would have to regenerate any code. – Doug Owings Jul 26 '12 at 22:19
  • @DougOwings, I wasn't able to get that to work either. At which point in the Players model is it supposed to go? Before or after `public $hasMany = 'Statistic';`? Also, why would I want to put it in the Player model if the view that I want this change to reflect upon is `statistics/add`? Thanks for all of your help! – bigmike7801 Jul 26 '12 at 22:25
  • @bigmike7801 It can go anywhere in the Player model. This defines an extra field `name` for the model so at any point in your application when you call `find('list')` on the Player model it will return an array whose indexes are the player ids and the values the players name. Try also adding `public $displayField = 'name';` in the Player model. Be sure you aren't regenerating models since that would overwrite your changes. – Doug Owings Jul 26 '12 at 22:45
  • I guess where I'm confused is I wanted to be able to run `cake bake` for my controllers and views so that the drop down list of players names is automatically populated with first and last name, however it appears your answer means that I have to go in an manually edit the views and add the reference to the virtual field. Am I correct in this? – bigmike7801 Jul 26 '12 at 22:54
  • Adding the `public $displayField = 'name';` after the $virtualFields did it! Thanks! – bigmike7801 Jul 26 '12 at 22:59