2

我正在考虑将 CakePHP (2.x) 用于我正在从事的新项目。该项目将拥有拥有客户的用户。客户端模型上会有默认字段,例如姓名、地址、电子邮件等。但我的客户希望用户能够向他们的客户添加自定义字段。

因此,User1 可能希望向其客户添加“最喜欢的颜色”字段,而 User2 可能希望向其客户添加“最喜欢的运动”字段。(这些只是示例)

有没有办法用 CakePHP 做到这一点?在模型的控制器、模型和视图已经烘焙之后,向模型添加字段的最佳解决方案是什么?

我的第一个想法是设置以下模型

用户(id、用户名、密码) hasMany: Clients

客户端(id、first_name、last_name、user_id)属于:用户 hasMany:ClientFields

ClientFieldKey ( id, field_name, user_id ) belongsTo: User hasMany:ClientFieldValues

ClientFieldValue ( id, client_field_key_id, field_value ) belongsTo: ClientFieldKey

ClientField ( id, client_id, client_field_value_id ) belongsTo: Client, ClientFieldValue

那么我可以有类似以下的东西

客户端(id:1,用户名:user1,密码:pass1,user_id:1)

客户端(id:2,用户名:user2,密码:pass2,user_id:1)

客户端(id:3,用户名:user3,密码:pass3,user_id:2)

客户端(id:4,用户名:user4,密码:pass4,user_id:2)

ClientFieldKey(id:1,field_name:颜色,user_id:1)

ClientFieldKey (id: 1, field_name: Sport, user_id: 2)

ClientFieldValue (id: 1, client_field_key_id: 1, field_value: red)

ClientFieldValue(id:2,client_field_key_id:1,field_value:蓝色)

ClientFieldValue(id:3,client_field_key_id:2,field_value:曲棍球)

ClientFieldValue(id:4,client_field_key_id:2,field_value:足球)

ClientField(id:1,client_id:1,client_field_value_id:2)

ClientField(id:2,client_id:2,client_field_value_id:1)

ClientField(id:3,client_id:3,client_field_value_id:3)

ClientField(id:4,client_id:4,client_field_value_id:4)

这意味着用户 1 创建了喜欢蓝色的客户端 1 和喜欢红色的客户端 2。用户 2 创建了喜欢曲棍球的客户 3,而客户 4 喜欢足球。

像这样的模型结构可以在 CakePHP 中工作吗?如果是这样,我将如何将字段添加到客户端添加和动态编辑表单以及我应该如何调用表?

4

2 回答 2

3

更新我不确定您是否更新了您的问题,或者我是否只是没有仔细阅读它,但是我已经更新了我的答案,以便它是关于客户而不是用户的。/更新

我会使用定义属性的附加表/模型(可能是键/值对)来执行此操作,并将其连接到Client使用hasMany关系,即Client hasMany Property.

这样,您以后可以将任意数量的属性分配给Client您喜欢的任何属性。

这是一个(未经测试的)示例:

属性表

properties
+------------------------------+
| id | client_id | key | value |
+------------------------------+

属性模型

class Property extends AppModel
{
    ...

    public $belongsTo = array
    (
        'Client' => array
        (
            'className' => 'Client',
            'foreignKey' => 'client_id'
        )
    );

    ...
}

客户端模型

class Client extends AppModel
{
    ...

    public $hasMany = array
    (
        'Property' => array
        (
            'className'  => 'Property',
            'foreignKey' => 'client_id',
            'dependent'  => true
        )
    );

    ...
}

向客户端添加属性

$data = array
(
    'Client' => array
    (
        'id' => 1234
    ),
    'Property' = array
    (
        array
        (
            'key' => 'favorite_color',
            'value' => 'green'
        ),
        array
        (
            'key' => 'favorite_sport',
            'value' => 'hockey'
        )
    )
);

$Client->saveAssociated($data);
于 2013-08-03T07:07:57.793 回答
0

我实际上想通了..不确定这是否是最好的方法,但效果很好。

我创建了以下模型:

  • 用户
  • 客户
  • 客户端字段键
  • 客户字段值

具有以下关系

用户

hasMany: Client, ClientFieldKey

客户

hasMany: ClientFieldValue

属于:用户

客户端字段键

hasMany: ClientFieldValue

属于:用户

客户字段值

belongsTo: Client, ClientFieldKey

然后,用户可以为字段创建键,并且在 ClientFieldKeyafterSave()回调中,每当创建 ClientFieldKey 时,我都会为每个用户客户端创建一个新的 ClientFieldValue。

// /Model/ClientFieldKey.php
public function afterSave($created) {
    if($created):
      $clientFieldValue = ClassRegistry::init('ClientFieldValue');
      $users_clients = $this->find('all', array(
        'conditions'=>'ClientFieldKey.id = '.$this->data['ClientFieldKey']['id'], 
        'contain'=>array('User'=>array('Client'=>array('fields'=>'id')))
      ));
      foreach($users_clients[0]['User']['Client'] as $users_client):
        $clientFieldValue->create();
        $clientFieldValue->set('client_field_key_id', $this->data['ClientFieldKey']['id']);
        $clientFieldValue->set('client_id', $users_client['id']);
        $clientFieldValue->save();
      endforeach;
  endif;
}

然后在我的客户端上设置添加/编辑/查看操作

// /Controller/ClientsController.php
public function add() {
      ...
  $this->Client->saveAssociated($this->request->data);
      ...   
  $clientFieldKeys = $this->Client->User->find('all', array('contain' => array('ClientFieldKeys' => array('fields'=>'id,key')), 'conditions' => 'User.id = '.$this->Auth->User('id')));
  $this->set('clientFieldKeys', $clientFieldKeys[0]['ClientFieldKeys']);
}

public function edit($id = null) {
      ...
  $this->Client->saveAll($this->request->data);
      ...
  $options = array('conditions' => array('Client.' . $this->Client->primaryKey => $id), 'contain'=>array('ClientFieldValue'=>array('ClientFieldKey')));
  $this->request->data = $this->Client->find('first', $options);
}

public function view($id = null) {
      ...
  $client = $this->Client->find('first', array(
    'conditions' => array('Client.' . $this->Client->primaryKey => $id),
    'contain' => array('User', 'ClientFieldValue' => array('ClientFieldKey'))
  ));
  $this->set('client', $client);
}

// /View/Clients/add.ctp
<?php if($clientFieldKeys): ?>
  <h2>Custom Fields</h2>
  <?php
    $count=0;
    foreach($clientFieldKeys as $cfk):
      echo $this->Form->hidden('ClientFieldValue.'.$count.'.client_field_key_id', array('value'=>$cfk['id']));
      echo $this->Form->input('ClientFieldValue.'.$count.'.value', array('type'=>'text', 'label'=>$cfk['key']));
      $count++;
    endforeach;
  ?>
<?php endif; ?>

// /View/Clients/edit.ctp
<?php if($this->data['ClientFieldValue']): ?>
  <h2>Custom Fields</h2>
  <?php
    $count=0;
    foreach($this->data['ClientFieldValue'] as $cfv):
      echo $this->Form->hidden('ClientFieldValue.'.$count.'.id');
      echo $this->Form->input('ClientFieldValue.'.$count.'.value', array('type'=>'text','label'=>$cfv['ClientFieldKey']['key']));
      $count++;
    endforeach;
  ?>
<?php endif; ?>

// /View/Clients/view.ctp
<?php if($client['ClientFieldValue']): ?>
  <h2>Custom Fields</h2>
  <?php foreach($client['ClientFieldValue'] as $clientFieldValue): ?>
    <dt><?php echo $clientFieldValue['ClientFieldKey']['key']; ?></dt>
      <dd>
        <?php echo $clientFieldValue['value']; ?>
        &nbsp;
      </dd>
  <?php endforeach; ?>
<?php endif; ?>
于 2013-08-12T11:23:16.967 回答