订购与FuelPHP的多对多关系

时间:2014-12-12 20:55:27

标签: orm lazy-loading eager-loading fuelphp fuelphp-orm

我在多对多关系上排序时遇到了问题。我想要实现的目标看起来应该是相当简单的,但经过大量的反对Fuel之后,我仍然无法让它发挥作用。

(顺便说一句,我发现这个问题或多或少都是asked before,但是因为(a)当时不可能对延迟加载关系进行排序,并且(b) )我已经了解了我所遇到的确切问题的更多细节,我认为值得作为一个单独的问题提出......)

以下是我遇到的问题:

我有一个"项目"模型。物品可以有孩子(也是物品),通过" items_items"通过多对多关系加入。带有' parent_id'的表格和' child_id'柱。 " items_items"表还有一个" sortorder"列,以便可以设置子项的顺序。

为这种关系创建一个单独的模型对我来说似乎有点过分,所以订单由更新子项目的观察者更新。保存父项时的排序顺序(通过" _event_after_save"在Model_Item上的方法)。这似乎工作正常。

然而,我遇到的问题是,我可以通过延迟加载并使用预先加载来获得排序顺序,但不能同时使用两者。无论哪一个有效,另一个都会抛出Fuel错误,因此目前让热切和延迟加载工作的唯一方法就是废弃' order_by'渴望加载的条款。以下是我尝试定义“孩子们”的三种方式。关系:

方法#1

  • 这是relevant page in FuelPHP's documentation建议的方法。
  • 在急切或延迟加载时没有错误,但无论如何,order_by不受尊重(子项按ID排序,而不是按排序顺序排序)

    'children' => array(
        'table_through'    => 'items_items',
        'key_through_from' => 'parent_id',
        'key_through_to'   => 'child_id',
        'model_to'         => 'Model_Item',
        'order_by' => array(
            'items_items.sortorder' => 'ASC'
        ),
    )
    

方法#2

  • 按需加载
  • 延迟加载导致燃料错误("未找到列:1054未知列' items_items.sortorder'在' order子句'" ; ) 这似乎是因为items_items被别名为“t0_ through”#39;在JOIN子句中,但不在ORDER BY子句中。

    'children' => array(
        'table_through'    => 'items_items',
        'key_through_from' => 'parent_id',
        'key_through_to'   => 'child_id',
        'model_to'         => 'Model_Item',
        'conditions'            => array(
            'order_by' => array(
                'items_items.sortorder' => 'ASC'
            ),
        )
    )
    

方法#3

  • 根据需要使用延迟加载
  • 因急切加载导致燃油错误(实际上与上面的#2相反)

    'children' => array(
        'table_through'    => 'items_items',
        'key_through_from' => 'parent_id',
        'key_through_to'   => 'child_id',
        'model_to'         => 'Model_Item',
        'conditions'            => array(
            'order_by' => array(
                't0_through.sortorder' => 'ASC'
            ),
        )
    )
    

在一个有点绝望的黑客中,我尝试通过定义两个独立的关系('孩子'和孩子')来结合上面的方法2和方法 - 一个用于急切加载,另一个用于延迟加载,但它仍然打破我的应用程序,因为它使删除过程抛出类似的错误。我可以尝试解决这个问题,但我觉得这只会破解黑客攻击。我想要的是一种可靠的方式来订购无论是热切还是懒惰的子项目。 Fuel的文档建议这应该是可行的(上面的方法#1),但我不能让它工作......

非常感谢任何帮助!

2 个答案:

答案 0 :(得分:2)

从ORM的角度来看," to_table"不存在。它只是定义为可以构造使关系工作所需的SQL。这也意味着" through_table"中的其他字段不受支持,它只能包含键值。

如果您想要直通表中的属性(附加列),它将成为数据库中的标准表,需要模型。你的多2关系然后分解为两个一对多的关系。

请注意,两者可以同时存在,因此如果您不需要查询或使用直通表中的列,您仍然可以使用多对多。

答案 1 :(得分:0)

我终于设法解决了这个问题。事实证明,当前发布的Fuel的ORM(版本1.7)存在问题。

对我有用的是将ORM更新为更新的开发版本(ORM的1.8 / develop分支上的60cc4eb576),然后在多对多关系上设置'order_by'这样:

...
'conditions' => array(
    'order_by' => array(
        'items_items.sortorder' => 'ASC'
    ),
)
...

这是上面方法2和方法3的组合,并不完全是documentation目前建议的语法,但似乎可以按预期/期望的方式进行预加载和延迟加载。