tags:

views:

46

answers:

3

I am trying to save a User, their Profile, and some tags and my join table that links the profile and the tags keeps getting messed up.

The profile model is called Instructor, the tag model is called Subject. The Instructor has a phone number and a zip code and for some reason CakePHP thinks these are the fields it should use when creating entries in my join table.

My Join table always comes out as:

id | instructor_id | subject_id |
1  | 90210         | 1          | // thinks that the zip code is an instructor_id
2  | 1112223333    | 1          | // thinks that the phone number is an instructor_id
3  | 1             | 1          | // thinks that user_id is an instructor_id
4  | 1             | 1          | // the actual instructor_id, this one's correct
5  | 90210         | 2          |
6  | 1112223333    | 2          |
3  | 1             | 2          |
4  | 1             | 2          |

My Models:

class Instructor extends AppModel
{
    var $name = 'Instructor';
    var $belongsTo = array('User', 'State');
    var $hasAndBelongsToMany = array(
        'Subject' => array(
            'className'                 => 'Subject',
            'joinTable'                 => 'instructors_subjects',
            'foreignKey'                => 'instructor_id',
            'associationForeignKey'     => 'subject_id',
            'unique'                    => true,
            'conditions'                => '',
            'fields'                    => '',
            'order'                     => '',
            'limit'                     => '',
            'offset'                    => '',
            'finderQuery'               => '',
            'deleteQuery'               => '',
            'insertQuery'               => ''
        )   
    );
}

class Subject extends AppModel
{
    var $name = 'Subject';
    var $hasAndBelongsToMany = array(
        'Instructor' => array(
            'className'                 => 'Instructor',
            'joinTable'                 => 'instructors_subjects',
            'foreignKey'                => 'subject_id',
            'associationForeignKey'     => 'instructor_id',
            'unique'                    => true,
            'conditions'                => '',
            'fields'                    => '',
            'order'                     => '',
            'limit'                     => '',
            'offset'                    => '',
            'finderQuery'               => '',
            'deleteQuery'               => '',
            'insertQuery'               => ''
        )   
    );
}

My Model Associations:

User hasOne Instructor
Instructor belongsTo User
Instructor hasAndBelongsToMany Subject
Subject hasAndBelongsToMany Instructor

My form data looks like:

Array
(
    [User] => Array
        (
            [username] => MrInstructor
            [password] => cddb06c93c72f34eb9408610529a34645c29c55d
            [group_id] => 2
        )

    [Instructor] => Array
        (
            [name] => Jimmy Bob
            [email] => [email protected]
            [phone] => 1112223333
            [city] => Beverly Hills
            [zip_code] => 90210
            [states] => 5
            [website] => www.jimmybobbaseballschool.com
            [description] => Jimmy Bob is an instructor.
            [user_id] => 1
            [id] => 1
        )

    [Subject] => Array
        (
            [name] => hitting, pitching
        )

)

My function for processing the form looks like:

    function instructor_register()
    {
        $this->set('groups', $this->User->Group->find('list'));
        $this->set('states', $this->User->Instructor->State->find('list'));

        if (!empty($this->data)) {
            // Set the group to Instructor
            $this->data['User']['group_id'] = 2;

            // Save the user data
            $user = $this->User->save($this->data, true, array(
                'username',
                'password',
                'group_id'
            ));

            // If the user was saved, save the instructor's info
            if (!empty($user)) {
                $this->data['Instructor']['user_id'] = $this->User->id;
                $instructor = $this->User->Instructor->save($this->data, true, array(
                    'user_id',
                    'name',
                    'email',
                    'phone',
                    'city',
                    'zip_code',
                    'state_id',
                    'website',
                    'description'
                ));

                // If the instructor was saved, save the rest
                if(!empty($instructor)) {
                    $instructorId = $this->User->Instructor->id;
                    $this->data['Instructor']['id'] = $instructorId;

                    // Save each subject seperately
                    $subjects = explode(",", $this->data['Subject']['name']);
                    foreach ($subjects as $_subject) {
                        // Get the correct subject format
                        $_subject = strtolower(trim($_subject));

                        $this->User->Instructor->Subject->create($this->data);

                        $this->User->Instructor->Subject->set(array(
                            'name' => $_subject
                        ));

                        $this->User->Instructor->Subject->save();

                        echo '
';
                        print_r($this->data);
                        echo '
'; } } } } }
A: 

Make sure you set the foreign keys in your models. As this is what Cake will be using, as you haven't listed your models this is the first place that I would look.

<?php

class Profile extends AppModel {
    var $name = 'Profile';                
    var $belongsTo = array(
        'User' => array(
            'className'    => 'User',
            'foreignKey'    => 'user_id'
        )
    );  
}
?>

More in the book, http://book.cakephp.org/view/78/Associations-Linking-Models-Together

Should also mention that your join table doesn't need an id field, just the two foreign keys is fine.

DavidYell
Thanks for your answer David. I added my models to the original post. I had my join table with an id field before and added it in a last ditch effort to make this thing work. Not sure what I was expecting.I'm still not seeing why all INT fields that are referenced in my form are being used as intructor_id's.
Jonnie
A: 

Have you tried saveAll method?

if(!empty($this->data)) {
  $this->User->saveAll($this->data, array('validate'=>'first'));
}
bancer
If I do a saveAll on User none of my subjects get saved. I need to be able to grab my Instructor's Id after it is saved to save each of the subjects in the loop.I tried saveAll, it doesn't seem to do that automatically.
Jonnie
A: 

I never did find out why CakePHP wanted to use all of my INT fields as ID's, but I was able to get this working by changing things up a little and utilizing a parse function from Jamie Fairhurst's tutorial.

Instead of saving each subject individually, they are put into an array and then saved at the same time with the instructor using a simple save().

Jonnie