BPD
BPD

Reputation: 81

how can I make a slug using fields from a different table using sluggable behaviour in cakephp

I have a Campaign model and I want to create a slug for each new campaign. I can do this easily with sluggable behaviour which is awesome but I'd like the slug to be created from the first_name and last_name field in the users table.

How can I do this? I've seen it asked a couple of times online but never answered. Surely it's possible!?!

Upvotes: 0

Views: 405

Answers (3)

Abba Bryant
Abba Bryant

Reputation: 4012

If you are going to use the sluggable behavior and both fields are from the same model - the solution I have used in the past is to:

a) Set up a virtual field for the User model

<?php
    class User extends AppModel
    {
        var $virtualFields = array(
            'full_name' => 'CONCAT(User.first_name, " ", User.last_name)'
        );
        ...
    }
?>

b) Use the Sluggable behavior on the virtualField.

<?php
    class User extends AppModel
    {
        ...
        public $actsAs = array(
            'Sluggable' => array(
                'label' => 'full_name',
                ...
            ),
            ...
        );
    }
?>

Upvotes: 0

Tyler
Tyler

Reputation: 2126

Assuming you have a relationship where Campaign belongsTo User, then in your Campaign model, just override the beforeValidate() function. You can override beforeSave() instead, but you will not get validation on the slug. Anyway:

function beforeValidate() {
    $return = parent::beforeValidate();

    if(isset($this->data['User']['first_name']) && isset($this->data['User']['last_name'])) {
        // assumes we're saving a campaign and a user at the same time w/ saveAll
        $this->data['Campaign']['slug'] = $this->data['User']['first_name'] . ' ' . $this->data['User']['last_name'];
    } elseif(isset($this->data['Campaign']['user_id'])) {
        // saving Campaign record w/ just user_id passed
        $user = $this->User->find('first', array('conditions'=>array('User.id'=>$this->data['Campaign']['user_id']), 'fields'=>array('User.first_name', 'User.last_name')));
        if($user) {
            $this->data['Campaign']['slug'] = $user['User']['first_name'] . ' ' . $user['User']['last_name'];
        }
    }
    return $return;
}        

Upvotes: 1

vindia
vindia

Reputation: 1678

Why do you want to use the Sluggable behavior? Isn't it easier to use the Inflector::slug method with first_name and last_name as parameters? Something like this:

$name = sprintf('%s %s', $first_name, $last_name);
$slug = Inflector::slug($name);
$this->Campaign->set('slug', $slug);
$this->Campaign->save();

Seems easier to me.

Upvotes: 0

Related Questions