【问题标题】:CakePHP: bi-directional self-referential hasMany Through associationsCakePHP:双向自引用 hasMany 关联
【发布时间】:2012-05-22 10:15:21
【问题描述】:

我正试图通过 CakePHP 中的关系了解双向自引用 hasMany(真是满口!)。

我正在开发一个图片匹配网站。

  • 图片通过“匹配”(连接模型)与其他图片相关联。
  • 每场比赛有两张图片,并存储当前评分和总票数。
  • 查看图片时,其任一方向的所有相关图片都应该可用(通过其匹配项)。

我首先通过与连接模型的关系定义了一个 hasMany。

pictures_matches 连接表有这样的结构:

id | picture_id | partner_id | rating | total_votes

我的匹配加入模型关联如下所示:

class PictureMatch extends AppModel {

...

    public $belongsTo = array(
        'Picture' => array(
            'className' => 'Picture',
            'foreignKey' => 'picture_id',
            'conditions' => '',
            'fields' => '',
            'order' => ''
        ),
        'Partner' => array(
            'className' => 'Picture',
            'foreignKey' => 'partner_id',
            'conditions' => '',
            'fields' => '',
            'order' => ''
        )
    );
}

每张图片都需要能够从任一方向访问其相关图片,但这是我无法掌握的地方。 看起来我需要保存关系的双方,但这会破坏存储在连接模型中的额外数据 - 有两个数据库条目,投票可能会因方向而异。

任何人都可以阐明在 CakePHP 中执行此操作的最佳方法吗?我很困惑。
是否可以动态创建反向关系?

【问题讨论】:

  • 你有没有想过这个问题?
  • Partner 部分下的 className 应该是“Partner”吗?

标签: cakephp associations has-many-through


【解决方案1】:

我认为这已被放弃,但它很容易解决——它与阶段有关

销毁存储在连接模型中的额外数据

这意味着您的保存正在运行 deleteAll 并在匹配时插入记录...而不是您需要查找并更新该记录...

这可以通过多种方式完成,但最简单的方法是在调用保存之前进行查找,然后将主键包含在匹配记录数据中。基本上不要将其保存为 HABTM,仅当您已经尝试查找现有匹配记录主键 (id) 并更新数据以保存时,才将其保存为 hasMany。

【讨论】:

    【解决方案2】:

    我不确定这是否是最好的解决方案,但如果你这样做了:

    public $belongsTo = array(
        'Picture1' => array(
            'className' => 'Picture',
            'foreignKey' => 'picture_id',
        ),
        'Picture2' => array(
            'className' => 'Picture',
            'foreignKey' => 'picture_id',
        ),
        'Partner' => array(
            'className' => 'Partner',
            'foreignKey' => 'partner_id',
        ),
    );
    

    然后,当您进行搜索时,您只需搜索 ($this->data['Picture1'] == $var || $this->data['Picture2'] == $var),只要您将 recursive 设置为 1 或 2,您就应该返回该 Picture 的所有相关数据。

    【讨论】:

      【解决方案3】:

      您可以通过 Model::bindModel() 动态创建实体,这是非常有用的东西,它可以让您动态绑定反向关系,或者更确切地说是您想要的任何方向。

      http://book.cakephp.org/2.0/en/models/associations-linking-models-together.html

      同样使用 Containable 行为,您可以创建无限链来检索您的关联日期。

      包含('Picture.PictureMatch.Partner.PictureMatch.Picture.....')

      基本上你可以循环遍历你的所有模型,只要每个链与下一个链有某种关联,以便更好地解释它的简单示例(请忽略其中的逻辑)

      圆属于正方形 正方形属于三角形

      所以 Triangle 与 Circle (直接)无关,但 Square 介于两者之间

      Circle->find('all', array('...', contain => array('Square.Triangle')); 
      

      或者为了获得更多乐趣,让我们一圈一圈地循环

      Circle->find('all', array('...', contain => array('Square.Trinagle.Square.Circle'));
      

      等等,当然这些例子是无用的,没有任何编程逻辑,但我希望你明白你可以在无限数量的关系中来回循环。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-12-08
        相关资源
        最近更新 更多