Php 如何使用Propel类委托

Php 如何使用Propel类委托,php,mysql,propel,Php,Mysql,Propel,我使用的是Propel 1.7-dev,正在玩弄表“继承”。我已经将Propel1和Phing设置为Git子模块,每个模块都在各自的主模块上签出。我构建了模型,我可以让层次结构正常工作,但如果我按照文档进行操作(可以说更干净),那么它就失败了 以下是我的模型的相关片段: <table name="process_step"> <column name="id" type="integer" required="true" primaryKey="true" autoIn

我使用的是Propel 1.7-dev,正在玩弄表“继承”。我已经将Propel1和Phing设置为Git子模块,每个模块都在各自的主模块上签出。我构建了模型,我可以让层次结构正常工作,但如果我按照文档进行操作(可以说更干净),那么它就失败了

以下是我的模型的相关片段:

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

    $processStepChild->setProcessStep($processStep);
    $processStepChild->save();
这样做的结果是,在我创建四个子行(每个都是不同类型)的地方,主键在父级(ProcessStep)中设置得很好,但在子级(ProcessStepLoad和其他)中都设置为零

即使我添加了中间保存,这也没有帮助。因此,在我看来,
$processStepChild->setProcessStep($processStep)
是问题所在-它应该确定它位于委托子级上,并将该子级的主键更改为提供的父级的键。它显然没有这样做

一些可能相关的问题:

  • 我是否正确理解课堂授权?据我所知,父键应该是一个自动递增的主键,并且必须在子键中作为手动主键使用,以形成层次关系。(旁白:我本以为有一种方法可以从父级自动确定类型,但鉴于它本身没有添加类型列,这是不可能的。这就是为什么我在父级中手动添加了
    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;
最后四个(到子表)当然是错误的:我们不能为每个子表都有一个外键,因为这需要每个子表扩展每个父表。事实证明,这种情况发生在孩子没有明确的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>
这让我可以按照文档使用级联保存,耶


故事的寓意:(a)我应该更仔细地阅读这些文档,(b)这些文档非常正确地说明了许多:1继承,(c)设置了外键后,1:1继承在Prope中也是可能的。

对,我刚刚切换到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;
最后四个(到子表)当然是错误的:我们不能为每个子表都有一个外键,因为这需要每个子表扩展每个父表。事实证明,这种情况发生在孩子没有明确的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>
这让我可以按照文档使用级联保存,耶

这个故事的寓意:(a)我应该更仔细地阅读文档,(b)文档说明了很多:1继承完全正确,(c)设置外键后,1:1继承在Propel中也是可能的