为什么Propel不会保存此查询,也不会出现任何错误?

时间:2012-09-18 07:12:07

标签: php mysql propel

我有一组像这样的表:

logbookresponsibilityuser

责任被重复使用 - 但每个日志只有一个不同的责任。每个职责都有一个用户。用户可以有多个职责(在多个日志上)。我有一张桌子可以将它们加在一起:

logbook_responsibility,有三个列(每个组成主键) - logbook_idresponsibility_iduser_id,这些都是外键。在我的schema.xml中,此表格设置为isCrossRef="true"

将责任更新为新用户时,我会以$_POST$_POST['responsibility'][2] = 5等形式传递给$_POST['responsibility'][7] = 2中的数组。我有一个应该是的函数更新它们:

public function updateResponsibilities($options = null)
{
  foreach ($options['responsibility'] as $k => $v) {      
    $user = UserQuery::create()
      ->filterByLogbook($this->logbook)
      ->findOneById($v);

    $logbookResponsibility = LogbookResponsibilityQuery::create()
      ->filterByLogbook($this->logbook)
      ->filterByResponsibilityId($k)
      ->findOne();

    if (is_null($user) || is_null($logbookResponsibility)) {
      break;
    }

    $logbookResponsibility->setUser($user)->save();
  }

  return true;
}

在这里,我遍历选项,使用提供的ID创建新用户,按当前日志过滤以确保他们被允许负责此日志,并抓住第一个。这工作正常(转储->toArray()

array(11) {
  ["Id"]=>
  int(2)
  ["CompanyId"]=>
  int(1)
  ["CurrentLogbookId"]=>
  int(1)
  ["OtherFieldsHere..."]=>
  // etc, etc

}

接下来,我获取了LogbookResponsibility,再次按当前日志和责任ID进行过滤。在此阶段,新用户ID显示正确:

array(3) {
  ["LogbookId"]=>
  int(1)
  ["ResponsibilityId"]=>
  int(1)
  ["UserId"]=>
  int(1)
}

然后我用之前抓取的用户更新此对象,然后保存。这样做我没有错误,之后检查对象显示该对象至少已更新:

array(3) {
  ["LogbookId"]=>
  int(1)
  ["ResponsibilityId"]=>
  int(1)
  ["UserId"]=>
  int(2)
}

但是,在没有接触任何其他内容的情况下,查看数据库之后,用户ID仍为1.我已经测试过运行如下查询:

UPDATE logbook_responsibility SET user_id = 1 WHERE logbook_id = 1 AND responsibility_id = 1;

......无误地工作。

我的实际问题有两个问题:

1)为什么不节约? (是否与我的交叉引用表有关?是否有超过2列的交叉引用表有问题?)

2)通常有更好的方式来实现我的设置吗? *(我尝试使用责任对象实现相同目标,但没有看到从那里更新logbook_responsibility的方法)*

乐于接受建议和实际答案!

1 个答案:

答案 0 :(得分:3)

正如评论中所建议的,当我运行getLastExecutedQuery()方法时,我使用save()来获取实际的查询运行,这是正在运行的查询(也解释了为什么没有错误) :

UPDATE `logbook_responsibility` SET `USER_ID`=3 WHERE
  logbook_responsibility.LOGBOOK_ID=1 AND
  logbook_responsibility.RESPONSIBILITY_ID=1 AND
  logbook_responsibility.USER_ID=3;

正如您所看到的,update语句在语法上是正确的,但问题似乎在于Propel如何更新主键 - 这让我想知道为什么我的用户ID列作为主键的一部分?

将用户作为主键的一部分是没有意义的,所以我删除了它,当然这使它成功了。仍然存在真正的问题, “如何在Propel中更新主键?” ,但最好留给{{3}解释。

如果有人有更好的解释,我会乐意将此标记为答案。