2

私は、いくつかの大規模な相互関係モデルを持つデータベースを持つクライアントを持っています。私たちが作成している $hasOne 関係で奇妙な「バグ」に遭遇しました。問題はこれです:

モデル UsersItems には、Users との $hasOne 関係があります。以下の通りです

var $hasOne = array(
    'Author' => array(
        'className' => 'User',
        'foreignKey' => 'id'
    )
);

これにより、ユーザー データがプルされ、これらのアイテムの別名「作成者」と結合されます (これは、ユーザーが「ブックマーク」のために選択したというコンテキストでは、ユーザーにも属します)。

UserItem の値がid3445 (テーブルの現在のサイズの範囲の中間) の場合、問題なく処理されます。

ただし、UserItem の がid5000 (テーブルの現在のサイズの上限) である場合、その $hasOne は から情報を取得できませんfind()。したがって、新しい「ブックマークされた」アイテムは作成者データを取得しないように見えますが、他の (「古い」) アイテムは問題なく取得できます。

これは何が原因でしょうか?

追加情報

クエリは次のとおりです。

SELECT `UsersItem`.`id`, `UsersItem`.`user_id`, `UsersItem`.`item_id`,
       `UsersItem`.`in_list`, `User`.`id`, `User`.`username`, `User`.`password`,
       `User`.`email`, `User`.`group_id`, `User`.`resethash`, `User`.`confirmhash`,
       `User`.`confirmed`, `Item`.`id`, `Item`.`user_id`, `Item`.`name`,
       `Item`.`category_id`, `Item`.`description`, `Item`.`pagelink`,
       `Item`.`purchaselink`, `Item`.`moderated`, `Item`.`image_filename`,
       `Item`.`votecount`, `Item`.`parent_id`, `Item`.`discover_order`,
       `Item`.`created`, `Item`.`slug`, `Item`.`normalized_name`,
       ((`Item`.`votecount`)/pow((3600*TIMEDIFF(`Item`.`created`, NOW()) + 12), .42)) AS `Item__rank`,
       `Author`.`id`, `Author`.`username`, `Author`.`password`, `Author`.`email`,
       `Author`.`group_id`, `Author`.`resethash`, `Author`.`confirmhash`,
       `Author`.`confirmed`
FROM `users_items` AS `UsersItem`
LEFT JOIN `users` AS `User` ON (`UsersItem`.`user_id` = `User`.`id`)
LEFT JOIN `items` AS `Item` ON (`UsersItem`.`item_id` = `Item`.`id`)
LEFT JOIN `users` AS `Author` ON (`Author`.`id` = `UsersItem`.`id`)
WHERE `UsersItem`.`user_id` = 1118
  AND `UsersItem`.`in_list` = 1
ORDER BY `UsersItem`.`id` DESC

第二補遺

このクエリ機能します。

SELECT `UsersItem`.`id`, `UsersItem`.`user_id`, `UsersItem`.`item_id`, `UsersItem`.`in_list`, `User`.`id`, `User`.`username`, `User`.`password`, `User`.`email`, `User`.`group_id`, `User`.`resethash`, `User`.`confirmhash`, `User`.`confirmed`, `Item`.`id`, `Item`.`user_id`, `Item`.`name`, `Item`.`category_id`, `Item`.`description`, `Item`.`pagelink`, `Item`.`purchaselink`, `Item`.`moderated`, `Item`.`image_filename`, `Item`.`yeekcount`, `Item`.`parent_id`, `Item`.`discover_order`, `Item`.`created`, `Item`.`slug`, `Item`.`normalized_name`, ((`Item`.`yeekcount`)/pow((3600*TIMEDIFF(`Item`.`created`, NOW()) + 12), .42)) AS `Item__rank`, `Author`.`id`, `Author`.`username`, `Author`.`password`, `Author`.`email`, `Author`.`group_id`, `Author`.`resethash`, `Author`.`confirmhash`, `Author`.`confirmed` FROM `users_items` AS `UsersItem` LEFT JOIN `users` AS `User` ON (`UsersItem`.`user_id` = `User`.`id`) LEFT JOIN `items` AS `Item` ON (`UsersItem`.`item_id` = `Item`.`id`) LEFT JOIN `users` AS `Author` ON (`Author`.`id` = `Item`.`user_id`) WHERE `UsersItem`.`user_id` = 1118 AND `UsersItem`.`in_list` = 1 ORDER BY `UsersItem`.`id` DESC

この特定のビットの違いに注意してください。

LEFT JOIN `users` AS `Author` ON (`Author`.`id` = `Item`.`user_id`)

以前、著者 ID として間違ったものを取得してidいたので、それが問題であることがわかりました。今、私は Cake にこの正しいクエリを生成させる方法を見つけようとしています...

4

4 に答える 4

4

たぶん、次のように、アイテムモデルで作成者の関係をhasOneではなくbelongsToに切り替える必要があります。

var $BelongsTo= array(
'Author' = array(
    'className' => 'User',
    'foreignKey' => 'user_id');

はそれを非常によく説明しています、belongsTo関係の外部キーはあなたが必要とするものです:

externalKey:現在のモデルで見つかった外部キーの名前。これは、複数のbelongsTo関係を定義する必要がある場合に特に便利です。このキーのデフォルト値は、他のモデルの下線付きの単数形の名前で、接尾辞は「_id」です。

私が助けてくれたことを願っています:)。

于 2011-05-04T10:40:13.153 に答える
3

私があなたの質問を正しく理解していれば、あなたの関連付けは次のようになっているはずです:

UserItem モデル:

var $belongsTo= array(
    'User', 'Item'
);

商品モデルについて:

var $hasMany = array(
    'UserItem'
);

var $hasOne = array(
    'Author' = array(
        'className' => 'User',
        'foreignKey' => 'id'
);

これが役立つことを願っています。

于 2011-05-04T09:24:16.737 に答える
2

ここでの答えはどれもうまくいきませんでした。良くも悪くも、私が最終的に行ったことは、作成者の名前の値を入力する仮想フィールドを作成することでした。

リレーションシップ モデルの問題は、対象のモデルを呼び出している場合にのみ適用されることです。私の場合、UsersItems テーブルと問題のアイテムを作成した人の名前との間には何の関係もありません (そしてそうあるべきではありません)。

仮想テーブルは、そのモデルの外観のすべてのインスタンスで呼び出されます。つまり、UsersItems->Items 関係であっても、Itemsその仮想フィールドにデータを入力します。

最終的に item.php モデル ファイルに作成したものは、次のようになりました。

var $virtualFields = array(
    'author' => 'SELECT `username` FROM `users` WHERE `id = Item.user_id`'
);

これがこの問題の適切な解決策であるかどうかについては、他の人からの返事を待ちますが、これまでのところ、私にとってうまくいったのはこれだけです. UsersItems テーブルには関連付けられauthor_idた列がないため、2 つのテーブルを関連付ける方法がわかりません。

于 2011-05-04T20:17:40.607 に答える
1

私のワイルドな推測では、ある時点で Author と UserItem の ID が同期しなくなったということです。しかし、生成されたクエリを見なければ、なんとも言えません。

于 2011-04-28T10:42:34.997 に答える