gpt4 book ai didi

php - 如何使用 Propel 类委托(delegate)

转载 作者:行者123 更新时间:2023-11-29 00:29:32 26 4
gpt4 key购买 nike

我正在使用 Propel 1.7-dev 并正在使用 class delegation即表“继承”。我已经将 Propel1 和 Phing 设置为 Git 子模块,并且每个子模块都在各自的主模块上 check out 。我的模型建立了,我可以让层次结构工作,但如果我按照文档(可以说更干净)来做,那么它就会失败。

这是我的模型的相关片段:

<table name="process_step">
<column name="id" type="integer" required="true" primaryKey="true" autoIncrement="true" />
<column name="process_id" type="integer" required="true" />
<column name="ordinal" type="integer" required="true" />
<column name="comment" type="varchar" size="256" />
<column name="type" type="enum" required="true"
valueSet="load, submit_form, check_page, get_links"
/>
<column name="is_enabled" type="boolean" required="true" default="false" />

<foreign-key foreignTable="process">
<reference local="process_id" foreign="id" />
</foreign-key>
</table>

<table name="process_step_load">
<column name="id" type="integer" required="true" primaryKey="true" />
<behavior name="delegate">
<parameter name="to" value="process_step" />
</behavior>
<column name="url" type="varchar" size="1024" />
<column name="method" type="varchar" size="6" required="true" default="get" />
</table>

实际上还有更多的子模型,但为了简洁起见,我已经删除了它们。

首先要注意的是文档显示父类和子类定义都具有自动递增的主键。然而,这是不可能的:主键必须在父级中设置,并复制到子级中(因为父级总是有一行)。我认为这是文档中的一个错误,但我会在这个问题之后提供一个补丁,以防我误解了什么。

所以,这是我的工作代码:

    $process = new Process();

$processStep = new ProcessStep();
$processStep->setOrdinal(1); // Simplified for brevitiy
$processStep->setType(1); // Ditto
$processStep->setProcess($process);

// This creates a primary key which we use below (i.e. a cascading
// save won't work)
$processStep->save();

$processStepChild->setId($processStep->getId());
$processStepChild->save();

文档是这样的:

    $process = new Process();

$processStep = new ProcessStep();
$processStep->setOrdinal(1); // Simplified for brevitiy
$processStep->setType(1); // Ditto
$processStep->setProcess($process);

$processStepChild->setProcessStep($processStep);
$processStepChild->save();

这样做的结果是,在我创建四个子行(每个子行都是不同类型)的情况下,主键在父级(ProcessStep)中设置得很好,但在子级(ProcessStepLoad 和其他)中都设置为零.

即使我添加了中间保存,这也无济于事。因此,在我看来 $processStepChild->setProcessStep($processStep) 是问题所在 - 它应该解决它在委托(delegate)子项上的问题,并将该子项的主键更改为键提供的 parent 。它显然没有这样做。

一些可能相关的问题:

  • 我是否正确理解了类委托(delegate)?据我所知,父键应该是一个自增主键,这必须在 child 中用作手动主键以形成层次关系。 (旁白:我原以为会有一种方法可以自动确定父级的类型,但鉴于它本身不添加类型列,所以这是不可能的。这就是我添加 enum 的原因 在父级手动)
  • 我使用 Propel master 而不是 1.6.x 正式版本会不会有什么问题?

最佳答案

是的,我刚刚切换到 MySQL 的 InnoDB 引擎,所以我可以使用约束,我的新父表如下所示。这说明哪里出了问题;表格上的关系是错误的:

CREATE TABLE `process_step`
(
`id` INTEGER NOT NULL AUTO_INCREMENT,
`process_id` INTEGER NOT NULL,
`ordinal` INTEGER NOT NULL,
`comment` VARCHAR(256),
`type` TINYINT NOT NULL,
`is_enabled` TINYINT(1) DEFAULT 0 NOT NULL,
PRIMARY KEY (`id`),
INDEX `process_step_FI_1` (`process_id`),
CONSTRAINT `process_step_FK_1`
FOREIGN KEY (`process_id`)
REFERENCES `process` (`id`),
CONSTRAINT `process_step_FK_2`
FOREIGN KEY (`id`)
REFERENCES `process_step_load` (`id`)
ON DELETE CASCADE,
CONSTRAINT `process_step_FK_3`
FOREIGN KEY (`id`)
REFERENCES `process_step_submit_form` (`id`)
ON DELETE CASCADE,
CONSTRAINT `process_step_FK_4`
FOREIGN KEY (`id`)
REFERENCES `process_step_check_page` (`id`)
ON DELETE CASCADE,
CONSTRAINT `process_step_FK_5`
FOREIGN KEY (`id`)
REFERENCES `process_step_get_links` (`id`)
ON DELETE CASCADE
) ENGINE=InnoDB;

最后四个(对于子表)当然是错误的:我们不能为每个子表都设置一个外键,因为这需要每个子表扩展每个父表。事实证明,这发生在 child 没有明确的 FK 的情况下。因此,我更改了模式中的类子级以包含父级的 FK:

<table name="process_step_load">
<column name="id" type="integer" required="true" primaryKey="true" />
<foreign-key foreignTable="process_step">
<reference local="id" foreign="id" />
</foreign-key>
<behavior name="delegate">
<parameter name="to" value="process_step" />
</behavior>
<column name="url" type="varchar" size="1024" />
<column name="method" type="varchar" size="6" required="true" default="get" />
</table>

这会在数据库中正确创建约束:

DROP TABLE IF EXISTS `process_step`;

CREATE TABLE `process_step`
(
`id` INTEGER NOT NULL AUTO_INCREMENT,
`process_id` INTEGER NOT NULL,
`ordinal` INTEGER NOT NULL,
`comment` VARCHAR(256),
`type` TINYINT NOT NULL,
`is_enabled` TINYINT(1) DEFAULT 0 NOT NULL,
PRIMARY KEY (`id`),
INDEX `process_step_FI_1` (`process_id`),
CONSTRAINT `process_step_FK_1`
FOREIGN KEY (`process_id`)
REFERENCES `process` (`id`)
) ENGINE=InnoDB;

-- ---------------------------------------------------------------------
-- process_step_load
-- ---------------------------------------------------------------------

DROP TABLE IF EXISTS `process_step_load`;

CREATE TABLE `process_step_load`
(
`id` INTEGER NOT NULL,
`url` VARCHAR(1024),
`method` VARCHAR(6) DEFAULT 'get' NOT NULL,
PRIMARY KEY (`id`),
CONSTRAINT `process_step_load_FK_1`
FOREIGN KEY (`id`)
REFERENCES `process_step` (`id`)
) ENGINE=InnoDB;

这允许我按照文档使用级联保存,耶!

故事的寓意:(a) 我应该更仔细地阅读文档,(b) 文档完美地正确说明了 many:1 继承,(c) 设置了外键后,1:1 继承也可以在推进。

关于php - 如何使用 Propel 类委托(delegate),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17261996/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com