【问题标题】:CakePHP Edit Not Loading foreign Table DataCakePHP 编辑不加载外部表数据
【发布时间】:2014-03-01 13:29:18
【问题描述】:

我正在尝试让我的编辑工作我需要在加载用户数据时加载联系人详细信息数据。我以与检索角色列表类似的方式设置数据。我也不知道如何根据模型进行检索,目前我正在对其进行硬编码以检索 28。非常感谢提供的任何帮助。

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);
    }
}

我的视图是这样设置的

<?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')); ?>

用户模型

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 模型

public $primaryKey = 'id';
public $displayField = 'name';  

【问题讨论】:

  • 这很奇怪...试试这个:从我的答案(第二个代码框)中查询,然后立即调试。看看是否有任何联系方式...顺便说一句,如果您的用户 ID 为 13,这意味着它将与 id 13 绑定联系方式。如果您的数据库结构不同(如果您有一些值为 13 的 user_id 字段)然后将这样的关系放入模型中(foreignKey => user_id)。
  • @Скачот 我有一个 id 为 47 和 contactdetail 为 27 的用户,这是由于这里和那里的一些错误。
  • 因此,如果您的表的结构已经像 contactdetail.userid 是 user.id 的外键,请在用户模型关系中定义它 ('foreignKey' => 'user_id')

标签: cakephp cakephp-model cakephp-2.4


【解决方案1】:

如果我没猜错的话,每个用户都有 1 个联系方式行。在这种情况下,您需要在 User 模型中定义:

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

这样,您的 id 将在两个表中同步。如果您不想将 id 设为外键,则不必这样做,这只是一个建议。

接下来,当您在控制器中检索数据时,您可以:

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

现在我不知道是否有自动化的方法来执行此操作,但我手动对数据进行排序以填写输入。我猜你会得到一个类似 array('User' => array(), 'ContactDetail' => array()) 的结构。

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

然后在您的视图中,只需将字段设置为输入数组:

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

这应该填写您的字段。当你去保存你的数据时,如果你的数组是这样的结构,你可以使用 saveAssociated():

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

编辑

如果您的关系被定义为 User hasMany ContactDetail,那么您需要像这样构造数据:

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

在你看来:

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

这仅适用于 1 行,如果您需要 1 个输入的子表上的更多行,请相应地执行您的逻辑。

【讨论】:

  • 在视图中,调试$this->request->data并粘贴结构
  • $request->data(array) User(array) id49 contact_detail_id29 passwordebc65bb3117645bffc9b51be05384d4751f5c76c role_id13 usernameEnzero2 Role(array) id13 nameAdministrator ContactDetail(array) id(null) address1(null) address2(null) country(null) ) email(null) 传真(null) interest_buy_property(null) interest_rent_property(null) 手机(null) name(null) newsletter(null) phone(null) postcode(null) surname(null) town(null)
  • 正如我所见,您的联系方式全部为空(并且来自查询)...该行甚至存在于您的数据库中吗?
  • 是的,数据库中有数据,我可以在 mysql 中看到它。contactdetailid 是 29
  • 你的关系有问题。用表格和模型结构更新问题
【解决方案2】:

一旦你的User模型hasOneContactDetail,你不需要再次检索信息,因为你已经在$this-&gt;request-&gt;data行完成,所有关联模型也会检索。

所以,您的Controller 看起来像这样:

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);
    }
}

而您的View,对于ContactDetail 的 字段如下所示:

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

对于与模型ContactDetail 相关的所有字段也是如此。您可以在此处找到更多详细信息:Saving Your Data

用户模型:

public $hasOne = array(
    'ContactDetail' => array(
        'className' => 'ContactDetail',
        'foreignKey' => 'user_id',
        'dependent' => true
    )
);

【讨论】:

  • @PauoloRodrigues 但一位用户只有一个联系方式,我为什么要使用 hasMany?
  • 对,你有debug($this-&gt;request-&gt;data)吗?您将找到ContactDetail 数据。顺便说一句,我编辑了我的答案。
  • 当我实现你的代码时,甚至我的用户名都没有开始加载。
  • 对不起,正确的是$this-&gt;User-&gt;read(null, $id)。我忘记了第一个参数中的null
  • 它正在加载用户但不是联系方式。它还加载角色,但联系人详细信息的数据为空。
【解决方案3】:

我发现的最佳解决方案是设置

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

通过这种方式加载联系人详细信息数据。虽然数据一旦保存并不会更新联系人详细信息。

为了我保存我用过

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

这完全有效

【讨论】:

  • 等一下,要让它工作,你必须在 users 表中有 contact_detail_idrole_id 字段,对吧?
  • @Скачот 是的,就是这样。
  • 那么应该是belongsTo。阅读有关模型绑定的更多信息。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多