Ela*_*ley 8 php mysql sql cakephp cakephp-1.3
我正在开发一个已经存在的cakephp 1.3项目,我需要在数据库中添加一个新表.我在我的控制器中有这个:
$conditions = array('ShootingPlacement.person_id' => $id, 'Email.person_id' => $id, 'Email.shooting_placement_id' => 'ShootingPlacement.id');
$shootingPlacements = $this->ShootingPlacement->find('all', compact('conditions'));
Run Code Online (Sandbox Code Playgroud)
它给了我这个错误:
Warning (512): SQL Error: 1054: Unknown column 'Email.person_id' in 'where clause' [CORE/cake/libs/model/datasources/dbo_source.php, line 684]
Run Code Online (Sandbox Code Playgroud)
这是它试图创建的查询:
SELECT `ShootingPlacement`.`id`, ... FROM `shooting_placements` AS `ShootingPlacement`
LEFT JOIN `people` AS `Person` ON (`ShootingPlacement`.`person_id` = `Person`.`id`)
LEFT JOIN `shootings` AS `Shooting` ON (`ShootingPlacement`.`shooting_id` = `Shooting`.`id`)
WHERE `ShootingPlacement`.`person_id` = 123688 AND `Email`.`person_id` = 123688 AND `Email`.`shooting_placement_id` = 'ShootingPlacement.id'
ORDER BY `lastname` ASC
Run Code Online (Sandbox Code Playgroud)
显然我的控制器代码是错误的,但我不确定如何将电子邮件表与ShootingPlacement表关联起来.我认为我的模型是正确的.到目前为止,如果我有这个:
$conditions = array('ShootingPlacement.person_id' => $id);
$shootingPlacements = $this->ShootingPlacement->find('all', compact('conditions'));
Run Code Online (Sandbox Code Playgroud)
它将从Shooting,ShootingPlacement和Person中检索行,我也希望Email也在那里.电子邮件有2个外键:一个来自ShootinPlacement,另一个来自Person.
这些是模型,我创建的唯一一个是电子邮件,其余的工作正常.
class Email extends AppModel
{
var $name = 'Email';
var $belongsTo = array
(
'Person' => array
(
'className' => 'Person',
'foreignKey' => 'person_id'
),
'ShootingPlacement' => array
(
'className' => 'ShootingPlacement',
'foreignKey' => 'shooting_placement_id'
)
);
}
class ShootingPlacement extends AppModel
{
var $name = 'ShootingPlacement';
var $belongsTo = array
(
'Person' => array
(
'className' => 'Person',
'foreignKey' => 'person_id',
'order' => 'lastname ASC'
),
'Shooting' => array
(
'className' => 'Shooting',
'foreignKey' => 'shooting_id'
)
);
}
class Person extends AppModel
{
var $name = 'Person';
var $belongsTo = array
(
'PersonOrigin' => array
(
'className' => 'PersonOrigin',
'foreignKey' => 'person_origin_id'
)
);
var $hasMany = array
(
'ShootingPlacement' => array
(
'className' => 'ShootingPlacement',
'foreignKey' => 'person_id',
'dependent' => false
)
);
}
class Shooting extends AppModel
{
var $name = 'Shooting';
var $belongsTo = array
(
'ShootingLocation' => array
(
'className' => 'ShootingLocation',
'foreignKey' => 'shooting_location_id'
),
'Emission' => array
(
'className' => 'Emission',
'foreignKey' => 'emission_id'
)
);
}
Run Code Online (Sandbox Code Playgroud)
我在视图中需要的是循环遍历ShootingPlacement变量,我需要它来包含针对ShootingPlacement和Person的特定id的Email表数据(正如您在查询中看到的,Person和ShootingPlacement已经处于关系中,我只是需要有电子邮件)
你应该非常小心地对待你所追求的关系。快速浏览其中一些答案,他们似乎建议您只需将电子邮件模型的联接添加到您的人员模型中,并依靠您的查找条件来确保您的查询不会耗尽服务器的内存。
我假设首先,您希望此电子邮件关系隐含在您对 Person 的所有查询中,否则您可以简单地在您想要的每个查询上指定联接。在这种情况下,您肯定希望使用模型关系来链接它。
您的代码显示 Shooting 和 ShootingPlacement (假设这是模型到模型的映射关系)都属于两个模型。顺便说一句,射击belongsTo发射 - 我们还没有在这里看到。我认为这不适用于当前场景。
现在,让我们假设一下不好的情况,因为您的电子邮件表有外键,所以它将是一种hasOne关系,而不是hasMany- 所以这就是您需要链接它的关系。我将把它链接到 ShootingPlacement 模型,因为这是您正在查询的模型,所以它应该是围绕它连接模型的中心点。结构方面,因为一切似乎都源自您的 Person 模型,我不得不建议您改为查询该模型。但到目前为止,它的设置方式将允许您从几乎任何地方进行查询,并且仍然检索几乎相同的结果(除了一些模型名称和表别名)。
纯粹是因为 Email 和 ShootingPlacement 之间的外键有不同的名称,而 CakePHP 1.3 不能很好地处理这个问题,我还建议您不要使用外键,而是将其作为条件放入关系中。
class ShootingPlacement extends AppModel
{
var $name = 'ShootingPlacement';
var $actsAs = array('Containable');
var $hasOne = array(
'Email' => array(
'className' => 'Email',
'foreignKey' => false,
'conditions' => array(
'Email.shooting_placement_id = ShootingPlacement.id',
'Email.person_id = ShootingPlacement.person_id'
)
)
);
var $belongsTo = array (
'Person' => array (
'className' => 'Person',
'foreignKey' => 'person_id',
'order' => 'lastname ASC'
),
'Shooting' => array (
'className' => 'Shooting',
'foreignKey' => 'shooting_id'
)
);
}
Run Code Online (Sandbox Code Playgroud)
我还在其中添加了可控制的行为。这使您可以从每个查询中控制您希望与主要模型结果一起返回的关联模型。它将默认为全部,但当您只想要特定的内容和/或出于内存原因时,它会很方便(如果您不限制它们或仅指定您想要的字段名称,这些类型的查询会很快破坏您的服务器内存)返回)。
现在,当您创建电子邮件模型时,我不建议通过再次将其链接回 ShootingPlacement 来使这些混乱的模型进一步复杂化。正如您所说,它还有一个 Person 模型的外键。因此,您可能希望对 Person 模型执行与上述完全相同的操作(当然,更改条件以反映 Person 外键)。这样你的模型就更加灵活了;它仍然会连接到 ShootingPlacement和Person,并且还允许您在需要时单独查询它,而无需其他关联模型。
文档
也可以看看