Question

I am trying to get my edit to work I need the contact detail data to load when the user data loads. I have set the data in a similar manner to how I am retrieving the list of roles. I also don't know how to retrieve according to the model currently I was hard-coding it to retrieve 28. Would greatly appreciate any help provided.

public function edit($id = null) {
    //Populate roles dropdownlist          
    $data = $this->User->Role->find('list', array('fields' => array('id', 'name')));
    $this->set('roles', $data);

    $data2 = $this->User->ContactDetail->find('first', array(

        'conditions' => array('ContactDetail.id' =>'28')));        
    $this->set('contactdetails', $data2);

    if (!$this->User->exists($id)) {
        throw new NotFoundException(__('Invalid user'));
    }
    if ($this->request->is(array('post', 'put'))) {
        if ($this->User->save($this->request->data)) {
            $this->Session->setFlash(__('The user has been saved.'));
            return $this->redirect(array('action' => 'index'));
        } else {
            $this->Session->setFlash(__('The user could not be saved. Please, try again.'));
        }
    } else {
        $options = array('conditions' => array('User.' . $this->User->primaryKey => $id));
        $this->request->data = $this->User->find('first', $options);
    }
}

my view is set up in the following manner

<?php echo $this->Form->create('User'); ?>
    <fieldset>
        <legend><?php echo __('Edit User'); ?></legend>
    <?php
        echo $this->Form->input('id');
                echo $this->Form->input('username');
        echo $this->Form->input('password');
        echo $this->Form->input('role_id');

                echo $this->Form->input('ContactDetail.name');
                echo $this->Form->input('ContactDetail.surname');
                echo $this->Form->input('ContactDetail.address1');
                echo $this->Form->input('ContactDetail.address2');
                echo $this->Form->input('ContactDetail.country');
                echo $this->Form->input('ContactDetail.email');
                echo $this->Form->input('ContactDetail.fax');


          ?>      
                <label>Are you interested in buying property in Malta?</label>
          <?php  
                $interest_buy = array('0'=>'no','1' => 'yes');
                echo $this->Form->input('ContactDetail.interest_buy_property',array('type'=>'radio','options'=>$interest_buy,'value'=>'0','legend'=>FALSE));
          ?>      
                <label>Are you interested in renting property in Malta?</label>
          <?php  
                $interest_rent = array('0'=>'no','1' => 'yes');
                echo $this->Form->input('ContactDetail.interest_rent_property',array('type'=>'radio','options'=>$interest_rent,'value'=>'0','legend'=>FALSE));
                echo $this->Form->input('ContactDetail.mobile');
                echo $this->Form->input('ContactDetail.phone');
                echo $this->Form->input('ContactDetail.postcode');
                echo $this->Form->input('ContactDetail.town');

                echo $this->Form->input('ContactDetail.newsletter',array('type'=>'checkbox','label'=>'Would you like to register for the newsletter?' ,'checked'=>'1','legend'=>FALSE,));
         ?>       
    ?>
    </fieldset>
<?php echo $this->Form->end(__('Submit')); ?>

User Model

public $primaryKey = 'id';

public $displayField = 'username';

public function bindNode($user) {
    return array('model' => 'Role', 'foreign_key' => $user['User']['role_id']);
}

public function beforeSave($options = array()) {
    $this->data['User']['password'] = AuthComponent::password(
                    $this->data['User']['password']
    );
    return true;
}

public $belongsTo = array(
    'Role' => array('className' => 'Role'));

public $hasOne = array(
    'ContactDetail' => array(
        'foreignKey' => 'id'));

public $actsAs = array('Acl' => array('type' => 'requester', 'enabled' => false));

public function parentNode() {
    if (!$this->id && empty($this->data)) {
        return null;
    }
    if (isset($this->data['User']['role_id'])) {
        $roleId = $this->data['User']['role_id'];
    } else {
        $roleId = $this->field('role_id');
    }
    if (!$roleId) {
        return null;
    } else {
        return array('Role' => array('id' => $roleId));
    }
}

}

ContactDetail Model

public $primaryKey = 'id';
public $displayField = 'name';  
Was it helpful?

Solution 3

The best solution I have found is by setting

public $belongsTo = array(
        'Role' => array('className' => 'Role')
    ,      'ContactDetail' => array('className' => 'ContactDetail'));

This way the contact detail data loads. Although the data once saved does not update contactdetails.

For me to save I used

$this->User->saveAll($this->request->data)

this worked fully

OTHER TIPS

If I get you right, you have 1 contact details row for each user. In this case, you need to define in your User model:

public $hasOne = array(
    'ContactDetail' => array(
        'foreignKey' => 'id',
    ),
);

Like this, your ids will be synced in both tables. If you don't want to make the id a foreign key, you don't have to, it's just a suggestion.

Next, when you retrieve your data in the controller, you can do:

$this->User->Behaviors->load('Containable');
$user = $this->User->find('first', array(
    'conditions' => array('User.id' => $id),
    'contain' => array('ContactDetail'),
));

Now I don't know if there is an automated way to do this, but I sort my data manually to fill in the inputs. I am guessing you will get a structure like array('User' => array(), 'ContactDetail' => array()).

$user['User']['ContactDetail'] = $user['ContactDetail'];
unset($user['ContactDetail']);
$this->request->data = $user;

Then in your view just set the fields as the input array:

$this->Form->create('User');
$this->Form->input('User.some_user_field');
$this->Form->input('User.ContactDetail.some_contact_detail_field');

This should fill in your fields. When you go save your data, if your array is structured like this, you can use saveAssociated():

$this->User->saveAssociated($this->request->data, array('deep' => true));

EDIT

In case your relation is defined as User hasMany ContactDetail, then you need to structure your data like this:

$this->request->data = array(
    'User' => array(
        // user data
        'ContactDetail' => array(
            [0] => array(
                //contact data
            ),
        ),
    ),
);

And in your view:

$this->Form->input('User.ContactData.0.field')

This is for 1 row only, If you need more rows on the child table with 1 input, do your logic accordingly.

Once your User model hasOne ContactDetail, you don't need retrieve the information twice, since you've done in $this->request->data line, all association model will retrieve too.

So, your Controller looks like this:

public function edit($id = null) {
    if (!$this->User->exists($id)) {
        throw new NotFoundException(__('Invalid user'));
    }

    // Roles
    $roles = $this->User->Role->find('list', array('fields' => array('id', 'name')));
    $this->set(compact('roles');

    if ($this->request->is(array('post', 'put'))) {
        if ($this->User->saveAll($this->request->data)) {
            $this->Session->setFlash(__('The user has been saved.'));
            return $this->redirect(array('action' => 'index'));
        } else {
            $this->Session->setFlash(__('The user could not be saved. Please, try again.'));
        }
    } else {
        $this->request->data = $this->User->read(null, $id);
    }
}

And your View, for ContactDetail's fields looks like this:

echo $this->Form->input('ContactDetail.name');

And so for all the fields related to the model ContactDetail. You can find more details here: Saving Your Data.

User model:

public $hasOne = array(
    'ContactDetail' => array(
        'className' => 'ContactDetail',
        'foreignKey' => 'user_id',
        'dependent' => true
    )
);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top