开发者

Need to make full names in cakePHP

If I have a person model with first_name and last_name, how do I create and display a full_name? I would like to display it at the top of my Edit and View views (i.e. "Edit Frank Luke") and other places. Simply dropping echoes to first_name and last_name isn't DRY.

I'm sorry if this is a very simple question, but nothing has yet worked.

Thank you, Frank Luke

Edit for clarity: Okay, I have a function on the person model.

function full_name() {
    return $this->Person->first_name . ' ' . $this->Person->last_name;
}

In the view, I call

echo $person['Person']['full_name']

This gives me a notice that I have an undefined index. What is the proper开发者_运维知识库 way to call the function from the view? Do I have to do it in the controller or elsewhere?


If what you are wanting is just to display a full name, and never need to do any database actions (comparisons, lookups), I think you should just concatenate your fields in the view.

This would be more aligned with the MVC design pattern. In your example you just want to view information in your database in a different way.

Since the action of concatenating is simple you probably don't save much code by placing it in a separate function. I think its easiest to do just in the view file.

If you want to do more fancy things ( ie Change the caps, return a link to the user ) I would recommend creating an element which you call with the Users data.


The arrays set by the save() method only return fields in the datbase, they do not call model functions. To properly use the function above (located in your model), you will need to add the following:

to the controller, in the $action method:

$this->set( 'fullname', $this->Person->full_name();
// must have $this-Person->id set, or redefine the method to include $person_id

in the view,

echo $fullname;

Basically, you need to use the controller to gather the data from the model, and assign it to the controller. It's the same process as you have before, where you assign the returned data from the find() call to the variable in the view, except youre getting the data from a different source.


There are multiple ways of doing this. One way is to use the afterFind-function in a model-class. See: http://book.cakephp.org/view/681/afterFind.

BUT, this function does not handle nested data very well, instead, it doesn't handles it al all! Therefore I use the afterfind-function in the app_model that walks through the resultset

function afterFind($results, $primary=false){
    $name = isset($this->alias) ? $this->alias : $this->name;
    // see if the model wants to attach attributes
    if (method_exists($this, '_attachAttributes')){
        // check if array is not multidimensional by checking the key 'id'
        if (isset($results['id'])) {
            $results = $this->_attachAttributes($results);
        } else {
            // we want each row to have an array of required attributes
            for ($i = 0; $i < sizeof($results); $i++) {
                // check if this is a model, or if it is an array of models
                if (isset($results[$i][$name]) ){
                    // this is the model we want, see if it's a single or array
                    if (isset($results[$i][$name][0]) ){
                        // run on every model
                        for ($j = 0; $j < sizeof($results[$i][$name]); $j++) {
                            $results[$i][$name][$j] = $this->_attachAttributes($results[$i][$name][$j]);
                        }
                    } else {
                        $results[$i][$name] = $this->_attachAttributes($results[$i][$name]);
                    }
                } else {
                    if (isset($results[$i]['id'])) {
                        $results[$i] = $this->_attachAttributes($results[$i]);
                    }
                }
            }
        }
    }
    return $results;
} 

And then I add a _attachAttributes-function in the model-class, for e.g. in your Person.php

function _attachAttributes($data) {
    if (isset($data['first_name']) && isset($data['last_name'])) {
        $data['full_name'] = sprintf("%s %s %s", $data['first_name'], $data['last_name']);
    }
    return $data;
}

This method can handle nested modelData, for e.g. Person hasMany Posts then this method can also attachAttributes inside the Post-model.

This method also keeps in mind that the linked models with other names than the className are fixed, because of the use of the alias and not only the name (which is the className).


You must use afterFind callback for it.


You would probably need to take the two fields that are returned from your database and concatenate them into one string variable that can then be displayed.


http://old.nabble.com/Problems-with-CONCAT-function-td22640199.html http://teknoid.wordpress.com/2008/09/29/dealing-with-calculated-fields-in-cakephps-find/

Read the first one to find out how to use the 'fields' key i.e. find( 'all', array( 'fields' => array( )) to pass a CONCAT to the CakePHP query builder.

The second link shows you how to merge the numeric indexes that get returned when you use custom fields back into the appropriate location in the returned results.

This should of course be placed in a model function and called from there.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜