3

我有一组像这样的表:

logbook, responsibility,user

职责被重用——但每个日志只有一项不同的职责。每个职责都有一个用户。一个用户可以有多个职责(在多个日志上)。我有一张桌子可以将它们连接在一起:

logbook_responsibility,三列(每列构成主键) -和logbook_id,它们都是外键。在我的这张表中设置了。responsibility_iduser_idschema.xmlisCrossRef="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 的方法)*

很高兴接受建议和实际答案!

4

1 回答 1

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;

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

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

如果有人有更好的解释,我很乐意将其取消标记为答案。

于 2012-09-18T13:49:29.303 回答