草庐IT

php - 插入 ORM 自引用外键

coder 2023-10-11 原文

我正在使用 Propel ORM 并且对 Propel 很陌生。我需要一些帮助从表中选择数据,但我无法正确查询。我有一个这样的表(注意:不是实际的表,而是相同的主体):

+---------------------+
| ID  | Page | Parent |
+---------------------+
| 1   |  A   |  0     |
| 2   |  B   |  0     |
| 3   |  C   |  2     |
| 4   |  D   |  3     |
| 5   |  E   |  1     |
| 6   |  F   |  0     |
| 7   |  G   |  3     |
| 8   |  H   |  4     |
| 9   |  I   |  6     |
| 10  |  J   |  5     |
+---------------------+

加载页面时,此表为我提供了树状结构。在使用 propel 之前,我有一个带有函数“loadPages”的类,它将内页嵌套在 Pages 类中名为 $nested 的数组中,看起来像这样(注意:不是实际函数,只是一个近似表示):

function loadPages($parent=0, $data){
    $sql = "sql query here to select pages where parent = $parent";
    while($results){
       $pages = new Pages();
       $pages->setId(blah blah);
       $pages->setPage(blah blah);
       $pages->setParent(blah blah);

       $innerPages = new Pages();
       /* load innerpages into the nested array */
       $innerPages->loadPages($pages->getId(), $pages->nested);

       array_push($data, $pages);
       return true;
    }
}

基本上我如何使用 Propel 做到这一点?我可以像这样轻松地提取父值为 0 的页面:

$pages = PagesQuery::create()
->filterByParent(0)
->find();

但我需要递归地将内页嵌套到它返回的对象中,即使 Propel 网站上有所有好的文档,我的努力也没有取得多大成果。

使用我的旧 Pages 类,如果我 print_r $data 我会得到这样的东西(这里只是一个使用上表的例子。):

Array(
   [0] => Pages Object
   (
    [id] => 2
    [page] => B
    [parent] => 0
    [nested] = Array(
       [0] => Pages Object
       (
        [id] => 3
        [page] => C
        [parent] => 2
       )
    )
)

我已经让这个工作了,但我不确定这是最好的方法。

function loadPages($parent=0, $siteId, &$arr){
        $arr = PagesQuery::create()
        ->filterBySiteId($siteId)
        ->filterByParentId($parent)
        ->find();

        foreach ($arr as $i => $v) {
            $arr[$i]->nested = '';
            loadPages($v->getId(), $siteId, $arr[$i]->nested);
        }

    }
    $site->pages = '';
    loadPages(0, $site->getId(), $site->pages);

我的模式没有 self 关系设置,所以我像这样向同一个表添加了一个外键,然后重新运行 propel 以重新创建类。我仍然不确定如何写出推进查询(我已经从模式中删除了几列只是为了节省空间)。抱歉,帖子现在变得很糟糕。

<table name="pages" phpName="Pages">
    <column name="id" type="integer" required="true" primaryKey="true" autoIncrement="true"/>
    <column name="userId" type="integer" required="false"/>
    <column name="siteId" type="integer" required="false"/>
    <column name="parentId" type="integer" required="false"/>
    <foreign-key foreignTable="users" phpName="Users" refPhpName="Pages">
         <reference local="userId" foreign="id"/>
        </foreign-key>
    <foreign-key foreignTable="sites">
          <reference local="siteId" foreign="id"/>
        </foreign-key>
        <foreign-key foreignTable="pages">
         <reference local="parentId" foreign="id"/>
        </foreign-key>
</table>

最佳答案

这不是您问题的直接答案,但它仍然是一个解决方案。

正如您在对问题的评论中提到的:nested-set 就是答案。

起初这听起来像是解决问题的方法,但 nested-set 是其他人遇到类似问题的结果。它经过深入研究,是一种流行的表示树木的方式。它的主要优势恰恰是能够管理可变深度树。

您提到您是 Propel 的新手,切换到嵌套集需要大量工作,所以我冒昧地假设您以前没有使用过 Propel 的行为。如果是这种情况,请务必阅读有关 Behaviors 的文档部分。 .

如果您现在喜欢 Propel,以后您会喜欢它!

要解决您的问题:请查看 NestedSet Behavior .与所有其他行为一样,很容易将其添加到您的架构中。重新生成您的模型,您只需对代码进行少量重构(示例将向您展示如何重构)。

(注意:如果您有现有数据库,则需要将该父链接迁移到嵌套集合结构。但这基本上是您应该关心的唯一问题。)

Using a RecursiveIterator 中提供了显示整棵树的示例部分。

关于php - 插入 ORM 自引用外键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15567976/

有关php - 插入 ORM 自引用外键的更多相关文章

  1. ruby - 如何在 Ruby 字符串中插入项目符号字符? - 2

    我正在尝试创建一个带有项目符号字符的Ruby1.9.3字符串。str="•"+"helloworld"但是,当我输入它时,我收到有关非ASCII字符的语法错误。我该怎么做? 最佳答案 你可以把Unicode字符放在那里。str="\u2022"+"helloworld" 关于ruby-如何在Ruby字符串中插入项目符号字符?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/1195

  2. ruby - 在 ruby​​ 中使用自动创建插入数组 - 2

    我想知道是否可以通过自动创建数组来插入数组,如果数组不存在的话,就像在PHP中一样:$toto[]='titi';如果尚未定义$toto,它将创建数组并将“titi”压入。如果已经存在,它只会推送。在Ruby中我必须这样做:toto||=[]toto.push('titi')可以一行完成吗?因为如果我有一个循环,它会测试“||=”,除了第一次:Person.all.eachdo|person|toto||=[]#with1billionofperson,thislineisuseless999999999times...toto.push(person.name)你有更好的解决方案吗?

  3. ruby-on-rails - 在方法调用中插入 Ruby? - 2

    在我的用户模型中,我有一堆属性,例如is_foos_admin和is_bars_admin,它们决定允许用户编辑哪些类型的记录。我想干掉我的编辑链接,目前看起来像这样:'edit'ifcurrent_user.is_foos_admin?%>...'edit'ifcurrent_user.is_bars_admin?%>我想做一个帮助程序,让我传入一个foo或bar并返回一个链接来编辑它,就像这样:助手可能看起来像这样(这不起作用):defedit_link_for(thing)ifcurrent_user.is_things_admin?link_to'Edit',edit_poly

  4. Ruby 将对象插入现有的已排序对象数组 - 2

    我有以下现有的Dog对象数组,它们按age属性排序:classDogattr_accessor:agedefinitialize(age)@age=ageendenddogs=[Dog.new(1),Dog.new(4),Dog.new(10)]我现在想插入一条新的狗记录,并将它放在数组中的正确位置。假设我想插入这个对象:another_dog=Dog.new(8)我想把它插入到数组中,让它成为数组中的第三项。这是一个人为的示例,旨在演示我特别想如何将一个项目插入到现有的有序数组中。我意识到我可以创建一个全新的数组并重新对所有对象进行排序,但这不是我的目标。谢谢!

  5. Ruby:如何将条件插入字符串连接 - 2

    在字符串连接中,是否可以直接在语句中包含条件?在下面的示例中,我希望仅当dear列表不为空时才连接"mydear"。dear=""string="hello"+"mydear"unlessdear.empty?+",goodmorning!"但是结果报错:undefinedmethod'+'fortrue我知道另一种方法是在这条语句之前定义一个额外的变量,但我想避免这种情况。 最佳答案 使用插值而不是连接更容易和更具可读性:dear=""string="hello#{'mydear'unlessdear.empty?},goodmo

  6. ruby - 在一个进程多个数据库连接 sinatra 应用程序中使用什么 ORM? - 2

    已检查ActiveRecord、DataMapper、Sequel:有些使用全局变量(静态变量)有些需要在使用模型加载源文件之前打开数据库连接。在使用不同数据库的sinatra应用程序中使用哪种ORM更好。 最佳答案 DataMapper专为多数据库使用而设计。你可以通过像DataMapper.setup(:repository_one,"mysql://localhost/my_db_name")这样的方式设置多个存储库。DataMapper随后会跟踪所有已在哈希中设置的存储库,您可以引用该哈希并将其用于范围界定:DataMapp

  7. ruby-on-rails - Scaffold Rails 3 View 中的外键下拉列表 - 2

    我使用脚手架和Rails3创建了2个模型。模型是位置和作业,每个作业都有一个位置。我在脚手架生成代码中创建了所需的引用调用,但是当我查看创建新作业的View时,我看到的只是一个文本框,我应该在其中添加location_id。我怎样才能让它变成下拉菜单以获得更好的用户体验? 最佳答案 想象一下,您有每个位置的titleAPI:http://apidock.com/rails/ActionView/Helpers/FormOptionsHelper/collection_select 关于r

  8. ruby-on-rails - 这个 C 和 PHP 程序员如何学习 Ruby 和 Rails? - 2

    按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visitthehelpcenter指导。关闭9年前。我来自C、php和bash背景,很容易学习,因为它们都有相同的C结构,我可以将其与我已经知道的联系起来。然后2年前我学了Python并且学得很好,Python对我来说比Ruby更容易学。然后从去年开始,我一直在尝试学习Ruby,然后是Rails,我承认,直到现在我还是学不会,讽刺的是那些打着简单易学的烙印,但是对于我这样一个老练的程序员来说,我只是无法将它

  9. ruby - 如何在数组中间插入一个数组? - 2

    我有一个Ruby数组[1,4]。我想在中间插入另一个数组[2,3],这样它就变成了[1,2,3,4]。我可以使用[1,4].insert(1,[2,3]).flatten实现这一点,但是有更好的方法吗? 最佳答案 您可以通过以下方式进行。[1,4].insert(1,*[2,3])insert()方法处理多个参数。因此,您可以使用splat运算符*将数组转换为参数。 关于ruby-如何在数组中间插入一个数组?,我们在StackOverflow上找到一个类似的问题:

  10. ruby - 用 ruby​​ 将 2 个破折号插入这个字符串的最短方法是什么? - 2

    这是字符串:04046955104021109我需要这样格式化:040469551-0402-1109用ruby​​做到这一点的最短/最有效的方法是什么? 最佳答案 两个简单的插入就可以了:example_string.insert(-9,'-').insert(-5,'-')负数表示您从字符串末尾开始计数。如果您愿意,也可以从头数起:example_string.insert(9,'-').insert(14,'-') 关于ruby-用ruby​​将2个破折号插入这个字符串的最短方法是

随机推荐