Cakephp 2.3: How to not use 'id' as the la

2019-01-29 13:14发布

问题:

I run into this dilemma a lot with Cakephp, and I'm prettty sure it's a consequence of my not following/understanding a convention somewhere. In any kind of belongsTo (hasAnd or otherwise), I generally find that since id tends to be the foreign key, it also ends up being what is displayed in dropdown menus, and this is of course semantically useless.

Here's an example of what I've generally done; I'm hoping someone can set me straight: (I'm just making up these tables because they make a good template for the general problem.)

Suppose:

Users table has columns id|firstname|lastname

Accounts has id|user_id

(nothing I'm doing is this simple, but this is the general form of the problem)

Using cake bake all, my Accounts/add view builds a dropdown for user_id that literally displays ID numbers. I have found a couple of ways around this, but they all involve basically assembling the information myself. I've either done it by building, in the controller, an $options array for the user_id dropdown of Accounts/add like so:

Controller

$users = $this->Account->User->find('list');

$options = Set::combine($users, '{n}.User.id', array('{0} {1}', '{n}.User.firstname', '{n}.User.lastname'));

View

echo $this->Form->input('user_id', array( 'div' => array( 'id' =>'UserId'), 'options'=>$options,'type'=>'select' ) )."\n\n";

Or else by:

Controller

$users = $this->Account->User->find('all', array('recursive' => 1) );

And then parsing the data at the View in almost the same fashion. In either case, I've always had the lingering certainty that I could be building my models in such a way that addresses this—it just seems like too basic a need to have not been addressed by such an extensive framework.

回答1:

For single column tables, a simple $displayField = 'column_name' is the answer.

But for concatenations of columns, there's a bit more code involved:

public $virtualFields = array("full_name"=>"CONCAT(first_name, ' ' ,last_name)");
public $displayField = 'full_name';

If its a really complicated $displayField, an afterFind solution may be necessary, but for most cases this is the solution.

Hope that helps.