3

私は次のようなテーブルのコレクションを持っています:

logbook、、responsibility_user

責任は再利用されますが、ログブックごとに1つの明確な責任のみがあります。各責任には1人のユーザーがいます。ユーザーは(複数のログブックで)複数の責任を持つことができます。これらを結合するためのテーブルがあります。

logbook_responsibility、3つの列(それぞれが主キーを構成します)-、、logbook_idおよびresponsibility_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;

...これはエラーなしで機能します。

の実際の質問は2つあります。

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;

ご覧のとおり、updateステートメントは構文的には正しいですが、問題はPropelが主キーを更新する方法にあるようです。これにより、ユーザーID列を主キーの一部として使用しているのはなぜでしょうか。

ユーザーを主キーの一部として使用するのは意味がなかったので、それを削除しました。もちろん、それで機能しました。「Propelで主キーを更新するにはどうすればよいですか?」という本当の疑問がまだ残っています。、しかしそれは他の誰かに説明を任せたほうがいいです。

誰かがより良い説明を持っているなら、私はこれを答えとしてマークを外して喜んでいます。

于 2012-09-18T13:49:29.303 に答える