与用户及其同事(朋友)一起考虑以下架构:
用户
User:
columns:
user_id:
name: user_id as userId
type: integer(8)
unsigned: 1
primary: true
autoincrement: true
first_name:
name: first_name as firstName
type: string(45)
notnull: true
last_name:
name: last_name as lastName
type: string(45)
notnull: true
email:
type: string(45)
notnull: true
unique: true
relations:
Collegues:
class: User
local: invitor
foreign: invitee
refClass: CollegueStatus
equal: true
onDelete: CASCADE
onUpdate: CASCADE
加入表:
CollegueStatus:
columns:
invitor:
type: integer(8)
unsigned: 1
primary: true
invitee:
type: integer(8)
unsigned: 1
primary: true
status:
type: enum(8)
values: [pending, accepted, denied]
default: pending
notnull: true
现在,假设我有两条记录,一条记录用户发出HTTP请求(登录用户),另一条记录表示他想要发送消息的用户。我想检查这些用户是否是同事。
问题:
我可能会做这样的事情:
public function areCollegues (User $user1, User $user2) {
// Ensure we load collegues if $user1 was fetched with DQL that
// doesn't load this relation
$collegues = $user1->get('Collegues');
$areCollegues = false;
foreach($collegues as $collegue) {
if($collegue['userId'] === $user2['userId']) {
$areCollegues = true;
break;
}
}
return $areCollegues;
}
但这看起来既不高效又不漂亮。我觉得它应该已经解决,因为自我引用关系很好用。
修改
鉴于我们在UserTable::construct()
中设置了以下内容:
$this->setAttribute(Doctrine::ATTR_COLL_KEY, 'userId');
然后上面的方法可能写成:
public function areCollegues (User $user1, User $user2) {
// Ensure we load collegues if $user1 was fetched with DQL that
// doesn't load this relation
$collegues = $user1->get('Collegues');
return isset($collegues[$user2['userId']);
}
这应该比第一个建议的方法更有效,但它仍然需要获取(并补充)比我想要的更多的记录。
答案 0 :(得分:1)
也许这不是你想要的,但为什么不只是查询表?效率更高:
$john = // invitor id
$lisa = // invited id
$q = Doctrine_Query::create()
->select('c.invitor')
->from('CollegueStatus c')
->where('c.invitor = ? AND c.invited = ? OR c.invitor = ? AND c.invited = ?, array($john, $lisa, $lisa, $john))
->limit(1);
$result = $q->execute(array(), Doctrine_Core::HYDRATE_NONE);
if (!empty($result)) echo 'they are colleagues';
我假设用户可以是“邀请”或“邀请者”,因此是AND OR AND构造。
你可以把它放在任何你想要的方法里面。