【发布时间】:2017-01-02 04:25:49
【问题描述】:
1..n 或 n..m 数据库表中的参考 ID 未自动设置。 请参阅下面的示例。我认为子表中的 client_id 是在任何地方自动设置的,但在我的情况下,在某些情况下它是 0。
要创建:Users.client_id 设置为应为 client.id 但 Contacts.client_id 始终为 0
数据库
CREATE TABLE `clients` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`service_paid` date DEFAULT NULL,
`service_contract_accepted` tinyint(1) NOT NULL,
`created` datetime DEFAULT NULL,
`modified` datetime DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
CREATE TABLE `users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`client_id` int(11) NOT NULL,
`contact_id` int(11) NOT NULL,
`email` varchar(255) NOT NULL,
`password` varchar(255) NOT NULL,
`role` char(50) DEFAULT 'user',
`token` varchar(255) DEFAULT NULL,
`token_expires` datetime DEFAULT NULL,
`activation_date` datetime DEFAULT NULL,
`active` tinyint(1) DEFAULT '0',
`created` datetime DEFAULT NULL,
`modified` datetime DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `contacts` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`client_id` int(11) NOT NULL,
`parent_id` int(11) DEFAULT NULL,
`contact_categories_id` int(11) DEFAULT NULL,
`company_indicator` tinyint(1) NOT NULL DEFAULT '0',
`company_name` varchar(100) DEFAULT NULL,
`salutation` varchar(200) DEFAULT NULL,
`name` varchar(50) NOT NULL,
`surname` varchar(50) DEFAULT NULL,
`street` varchar(50) NOT NULL,
`street_number` varchar(5) NOT NULL,
`postal_code` int(5) NOT NULL,
`city` varchar(99) NOT NULL,
`country` varchar(20) NOT NULL,
`lat` float DEFAULT NULL,
`lng` float DEFAULT NULL,
`letter_salutation` text,
`phonenumber_business` varchar(45) DEFAULT NULL,
`mobilenumber_business` varchar(45) DEFAULT NULL,
`phonenumber_private` varchar(45) DEFAULT NULL,
`mobilenumber_private` varchar(45) DEFAULT NULL,
`faxnumber_business` varchar(45) DEFAULT NULL,
`faxnumber_private` varchar(45) DEFAULT NULL,
`email` varchar(45) DEFAULT NULL,
`website` varchar(200) DEFAULT NULL,
`logo` varchar(100) DEFAULT NULL,
`sepa_glid` varchar(45) DEFAULT NULL,
`vat_number` varchar(45) DEFAULT NULL,
`taxident_number` varchar(45) DEFAULT NULL,
`tax_office` varchar(45) DEFAULT NULL,
`important_day` date DEFAULT NULL,
`important_day_text` varchar(45) DEFAULT NULL,
`important_day_resubmissin` varchar(45) DEFAULT NULL,
`important_day_reminder` tinyint(1) DEFAULT NULL,
`notes` text,
`created` datetime DEFAULT NULL,
`modified` datetime DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
查看
在以下客户/注册 VIEW - 我已经创建了这个表单
<fieldset>
<?= $this->Form->create($client) ?>
<h2 id="content"><?= __('Firmendaten') ?></h2>
<?= $this->Form->input('users.0.contact.company_indicator', ['type' => 'hidden', 'value' => '1']); ?>
<?= $this->Form->input('users.0.contact.company_name', ['type' => 'text', 'label'=> false, 'placeholder' => __('Firmenname')]); ?>
<?= $this->Form->input('users.0.contact.surname', ['type' => 'text', 'label'=> false, 'placeholder' => __('Vorname')]); ?>
<?= $this->Form->input('users.0.contact.name', ['type' => 'text', 'label'=> false, 'placeholder' => __('Nachname')]); ?>
<?= $this->Form->input('users.0.contact.street', ['type' => 'text', 'label'=> false, 'placeholder' => __('Straße'), 'required' => true]); ?>
<?= $this->Form->input('users.0.contact.street_number', ['type' => 'text', 'label'=> false, 'placeholder' => __('Nr.'), 'required' => true]); ?>
<?= $this->Form->input('users.0.contact.postal_code', ['type' => 'text', 'label'=> false, 'placeholder' => __('PLZ'), 'required' => true]); ?>
<?= $this->Form->input('users.0.contact.city', ['type' => 'text', 'label'=> false, 'placeholder' => __('Stadt'), 'required' => true]); ?>
<?= $this->Form->input('users.0.contact.country', ['type' => 'text', 'label'=> false, 'placeholder' => __('Land'), 'required' => true]); ?>
<h2 id="content"><?= __('Anwenderdaten') ?></h2>
<?= $this->Form->input('users.0.email', ['type' => 'email', 'label'=> false, 'placeholder' => __('Email'), 'required' => true]); ?>
<?= $this->Form->input('users.0.confirm_email', ['type' => 'email', 'label'=> false, 'placeholder' => __('Email wiederholen'), 'required' => true]); ?>
<?= $this->Form->input('users.0.password', ['type' => 'password', 'label'=> false, 'placeholder' => __('Passwort'), 'required' => true]); ?>
<?= $this->Form->input('users.0.confirm_password', ['type' => 'password', 'label'=> false, 'placeholder' => __('Passwort wiederholen'), 'required' => true]); ?>
<?= $this->Form->input('service_contract_accepted', ['type' => 'checkbox', 'label' => __('AGB'), 'default' => 0, 'hiddenField' => false, 'required' => true]); ?>
<?= $this->Form->button(__('Submit')) ?>
<?= $this->Form->end() ?>
</fieldset>
控制器
这是在 ClientsController.php 中处理的
public function register()
{
$client = $this->Clients->newEntity();
if ($this->request->is('post')) {
$client = $this->Clients->patchEntity($client, $this->request->data, ['associated' => ['Users', 'Users.Contacts' ]]);
if ($this->Clients->save($client)) {
$this->Flash->success(__('The user has been saved.'));
return $this->redirect(['controller' => 'Contracts', 'action' => 'index']);
} else {
debug($client);
$this->Flash->error(__('The user could not be saved. Please, try again.'));
}
}
$this->set(compact('client'));
$this->set('_serialize', ['client']);
}
型号
我已经把它们都烤好了……我们开始吧
class ClientsTable extends Table
{
public function initialize(array $config)
{
parent::initialize($config);
$this->table('clients');
$this->displayField('name');
$this->primaryKey('id');
$this->addBehavior('Timestamp');
$this->hasMany('AccountAllocationsTodefine', [
'foreignKey' => 'client_id'
]);
$this->hasMany('AccountingPeriodDetails', [
'foreignKey' => 'client_id'
]);
$this->hasMany('AccountingPeriods', [
'foreignKey' => 'client_id'
]);
$this->hasMany('Accounts', [
'foreignKey' => 'client_id'
]);
$this->hasMany('AccountsFrameworks', [
'foreignKey' => 'client_id'
]);
$this->hasMany('AllocationValuesTodefine', [
'foreignKey' => 'client_id'
]);
$this->hasMany('BankAccounts', [
'foreignKey' => 'client_id'
]);
$this->hasMany('ContactCategories', [
'foreignKey' => 'client_id'
]);
$this->hasMany('Contacts', [
'foreignKey' => 'client_id'
]);
$this->hasMany('Contracts', [
'foreignKey' => 'client_id'
]);
$this->hasMany('Counter', [
'foreignKey' => 'client_id'
]);
$this->hasMany('CounterTypes', [
'foreignKey' => 'client_id'
]);
$this->hasMany('CounterValues', [
'foreignKey' => 'client_id'
]);
$this->hasMany('DataProperties', [
'foreignKey' => 'client_id'
]);
$this->hasMany('DataPropertyValues', [
'foreignKey' => 'client_id'
]);
$this->hasMany('DebitPosition', [
'foreignKey' => 'client_id'
]);
$this->hasMany('Employees', [
'foreignKey' => 'client_id'
]);
$this->hasMany('EnergyCertificates', [
'foreignKey' => 'client_id'
]);
$this->hasMany('Fees', [
'foreignKey' => 'client_id'
]);
$this->hasMany('Files', [
'foreignKey' => 'client_id'
]);
$this->hasMany('Floors', [
'foreignKey' => 'client_id'
]);
$this->hasMany('GlobalSettingsHeaders', [
'foreignKey' => 'client_id'
]);
$this->hasMany('Heatings', [
'foreignKey' => 'client_id'
]);
$this->hasMany('Objects', [
'foreignKey' => 'client_id'
]);
$this->hasMany('Owners', [
'foreignKey' => 'client_id'
]);
$this->hasMany('Postings', [
'foreignKey' => 'client_id'
]);
$this->hasMany('RentPrices', [
'foreignKey' => 'client_id'
]);
$this->hasMany('ServiceProviders', [
'foreignKey' => 'client_id'
]);
$this->hasMany('SettingsHeaders', [
'foreignKey' => 'client_id'
]);
$this->hasMany('SettingsValues', [
'foreignKey' => 'client_id'
]);
$this->hasMany('TemplateAccounts', [
'foreignKey' => 'client_id'
]);
$this->hasMany('TemplateAllocationFormulas', [
'foreignKey' => 'client_id'
]);
$this->hasMany('Templates', [
'foreignKey' => 'client_id'
]);
$this->hasMany('TenantDeposits', [
'foreignKey' => 'client_id'
]);
$this->hasMany('Tenants', [
'foreignKey' => 'client_id'
]);
$this->hasMany('Units', [
'foreignKey' => 'client_id'
]);
$this->hasMany('Users', [
'foreignKey' => 'client_id'
]);
}
public function validationDefault(Validator $validator)
{
$validator
->integer('id')
->allowEmpty('id', 'create');
$validator
->boolean('active')
->requirePresence('active', 'create')
->notEmpty('active');
$validator
->date('service_paid')
->allowEmpty('service_paid');
$validator
->boolean('service_contract_accepted')
->requirePresence('service_contract_accepted', 'create')
->notEmpty('service_contract_accepted');
return $validator;
}
}
class UsersTable extends Table
{
public function initialize(array $config)
{
parent::initialize($config);
$this->table('users');
$this->displayField('username');
$this->primaryKey('id');
$this->addBehavior('Timestamp');
$this->belongsTo('Clients', [
'foreignKey' => 'client_id',
'joinType' => 'INNER'
]);
$this->belongsTo('Contacts', [
'foreignKey' => 'contact_id',
'joinType' => 'INNER'
]);
$this->hasMany('Employees', [
'foreignKey' => 'user_id'
]);
}
public function validationDefault(Validator $validator)
{
$validator
->integer('id')
->allowEmpty('id', 'create');
$validator
->email('email')
->requirePresence('email', 'create')
->notEmpty('email')
->add('email', 'unique', ['rule' => 'validateUnique', 'provider' => 'table']);
$validator
->requirePresence('password', 'create')
->notEmpty('password');
$validator
->allowEmpty('role');
$validator
->allowEmpty('token');
$validator
->dateTime('token_expires')
->allowEmpty('token_expires');
$validator
->dateTime('activation_date')
->allowEmpty('activation_date');
$validator
->boolean('active')
->allowEmpty('active');
return $validator;
}
public function buildRules(RulesChecker $rules)
{
$rules->add($rules->isUnique(['email']));
$rules->add($rules->existsIn(['client_id'], 'Clients'));
$rules->add($rules->existsIn(['contact_id'], 'Contacts'));
return $rules;
}
}
class ContactCategoriesTable extends Table
{
public function initialize(array $config)
{
parent::initialize($config);
$this->table('contact_categories');
$this->displayField('id');
$this->primaryKey('id');
$this->addBehavior('Timestamp');
$this->belongsTo('Clients', [
'foreignKey' => 'client_id',
'joinType' => 'INNER'
]);
$this->belongsTo('SettingsValues', [
'foreignKey' => 'settings_value_id',
'joinType' => 'INNER'
]);
}
public function validationDefault(Validator $validator)
{
$validator
->integer('id')
->allowEmpty('id', 'create');
$validator
->boolean('active')
->requirePresence('active', 'create')
->notEmpty('active');
return $validator;
}
public function buildRules(RulesChecker $rules)
{
$rules->add($rules->existsIn(['client_id'], 'Clients'));
$rules->add($rules->existsIn(['settings_value_id'], 'SettingsValues'));
return $rules;
}
}
问题
一切正常,除了 DB 中的 Contacts.client_id 始终设置为 0。 我认为 cakephp 自己处理引用 id 并自动设置它们。
我应该如何扩展我的代码来自动设置这个 client_id?
client_id 确实在我所有的表中,我需要在任何地方自动设置它。
谢谢 比伦特
【问题讨论】:
-
您所看到的是(当前)预期的行为。为什么首先在
users和contacts表中复制客户端ID?联系人真的可以在没有用户的情况下存在吗?鉴于用户和联系人之间通过其自动递增主键的硬链接,这是在乞求问题。 -
如果你没有为该列添加任何非空值并且数据类型为整数,它将自动为空,将其更改为允许空
-
client_id 在某种程度上是我对整个应用程序的强制要求。我在每个表中都有这个 client_id,并且可以直接从每个表中选择当前客户端的有效数据。我想确保数据不属于的其他人不会看到任何数据。是否有关于此行为的文档?如果我理解正确,则没有设置第二级。
$this->Form->input('**users.0.contact.street**',... $this->Form->input('users.0.contact.street_number', ... -
您好 NDM,我不明白这种行为。我在联系人
$rules->add($rules->existsIn(['client_id'], 'Clients'));中有此代码@为什么没有真正检查?客户表中没有0 ID,为什么插入表中没有任何异常? -
这可能取决于
0的确切生成位置和方式。为了让规则测试一个值,必须预先设置(当然),并且必须将属性标记为脏。我建议您在规则中添加一些断点,并检查何时以及使用何种数据调用它,以及它在何处退出。从这里我能做的就是猜测。