使用 hasMany 时出错。我得到不相关的对象
Error when use hasMany. I get non related objects
用户关系:
public function events() {
return $this->hasMany('Events', 'user_id');
}
事件关系:
public function user() {
return $this->belongsTo('User');
}
我想获取当前月份的所有事件,除了今天的事件,所以我使用:
$pets= Auth::user()->events()
->where(function($query) use($myYear, $myMonth, $myDay) {
$query->whereYear('start_date', '=', $myYear);
$query->whereMonth('start_date', '=', $myMonth);
$query->whereDay('start_date', '!=', $myDay);
})->orWhere(function($query) use($myYear, $myMonth, $myDay) {
$query->whereYear('end_date', '=', $myYear);
$query->whereMonth('end_date', '=', $myMonth);
$query->whereDay('end_date', '!=', $myDay);
})->get();
但这会检索所有用户的所有 events
。我需要在-get()
之前添加->where("user_id", Auth::user()->id)
,我不知道为什么。
谁能帮我解决这个问题?
您没有保留 $query
的引用以传递闭包,请这样尝试。
$query = Auth::user()->events();
$query->where(function($query) use($myYear, $myMonth, $myDay) {
$query->whereYear('start_date', '=', $myYear);
$query->whereMonth('start_date', '=', $myMonth);
$query->whereDay('start_date', '!=', $myDay);
});
$query->orWhere(function($query) use($myYear, $myMonth, $myDay) {
$query->whereYear('end_date', '=', $myYear);
$query->whereMonth('end_date', '=', $myMonth);
$query->whereDay('end_date', '!=', $myDay);
})
$pets = $query->get();
如何解决:在 mySQL 中(如果是 Lavavel,我假设您正在使用)只需打开 "general log"。这是关于如何做到这一点的相当不错的 Whosebug:How to enable MySQL Query Log?
这将记录对 MySQL 的所有调用,您将能够看到构造。
接下来是猜测:您可能会发现查询最终为:
SELECT events FROM events
WHERE
userID = :userID
AND (not start date)
OR (not end date)
因为 AND 的计算优先级更高 (http://dev.mysql.com/doc/refman/5.7/en/operator-precedence.html) 这与
相同
SELECT events FROM events
WHERE
(
userID = :userID
AND
(not start date)
)
OR
(not end date)
因此将包括第二个查询中的任何人,而不仅仅是用户。
但是你需要的是
SELECT events FROM events
WHERE
userID = :userID
AND
(
(not start date)
OR
(not end date)
)
你如何 "fixed" 它,但通过在末尾添加额外的 "AND",你得到
SELECT events FROM events
WHERE
userID = :userID
AND (not start date)
OR (not end date)
AND userID = :userID
与
相同
SELECT events FROM events
WHERE
(
userID = :userID
AND
(not start date)
)
OR
(
(not end date)
AND
userID = :userID
)
以迂回的方式做你想做的事...
问题出在您的 or
语句上。您的查询当前如下所示:
where relationship_condition AND start_date_condition OR end_date_condition
在操作的逻辑顺序中,AND
s 在 OR
s 之前执行,所以这等同于:
where (relationship_condition AND start_date_condition) OR end_date_condition
这意味着任何与您的 end_date_condition
匹配的记录都将被返回,无论它们是否与 relationship_condition
匹配。为了纠正这个问题,您需要正确分组您的 OR
条件,因此它看起来像这样:
where relationship_condition AND (start_date_condition OR end_date_condition)
因此,您的代码应如下所示:
$pets= Auth::user()->events()
->where(function ($query) use ($myYear, $myMonth, $myDay) {
return $query
->where(function ($query) use ($myYear, $myMonth, $myDay) {
return $query
->whereYear('start_date', '=', $myYear)
->whereMonth('start_date', '=', $myMonth)
->whereDay('start_date', '!=', $myDay);
})
->orWhere(function ($query) use($myYear, $myMonth, $myDay) {
return $query
->whereYear('end_date', '=', $myYear)
->whereMonth('end_date', '=', $myMonth)
->whereDay('end_date', '!=', $myDay);
});
})
->get();
用户关系:
public function events() {
return $this->hasMany('Events', 'user_id');
}
事件关系:
public function user() {
return $this->belongsTo('User');
}
我想获取当前月份的所有事件,除了今天的事件,所以我使用:
$pets= Auth::user()->events()
->where(function($query) use($myYear, $myMonth, $myDay) {
$query->whereYear('start_date', '=', $myYear);
$query->whereMonth('start_date', '=', $myMonth);
$query->whereDay('start_date', '!=', $myDay);
})->orWhere(function($query) use($myYear, $myMonth, $myDay) {
$query->whereYear('end_date', '=', $myYear);
$query->whereMonth('end_date', '=', $myMonth);
$query->whereDay('end_date', '!=', $myDay);
})->get();
但这会检索所有用户的所有 events
。我需要在-get()
之前添加->where("user_id", Auth::user()->id)
,我不知道为什么。
谁能帮我解决这个问题?
您没有保留 $query
的引用以传递闭包,请这样尝试。
$query = Auth::user()->events();
$query->where(function($query) use($myYear, $myMonth, $myDay) {
$query->whereYear('start_date', '=', $myYear);
$query->whereMonth('start_date', '=', $myMonth);
$query->whereDay('start_date', '!=', $myDay);
});
$query->orWhere(function($query) use($myYear, $myMonth, $myDay) {
$query->whereYear('end_date', '=', $myYear);
$query->whereMonth('end_date', '=', $myMonth);
$query->whereDay('end_date', '!=', $myDay);
})
$pets = $query->get();
如何解决:在 mySQL 中(如果是 Lavavel,我假设您正在使用)只需打开 "general log"。这是关于如何做到这一点的相当不错的 Whosebug:How to enable MySQL Query Log?
这将记录对 MySQL 的所有调用,您将能够看到构造。
接下来是猜测:您可能会发现查询最终为:
SELECT events FROM events
WHERE
userID = :userID
AND (not start date)
OR (not end date)
因为 AND 的计算优先级更高 (http://dev.mysql.com/doc/refman/5.7/en/operator-precedence.html) 这与
相同SELECT events FROM events
WHERE
(
userID = :userID
AND
(not start date)
)
OR
(not end date)
因此将包括第二个查询中的任何人,而不仅仅是用户。
但是你需要的是
SELECT events FROM events
WHERE
userID = :userID
AND
(
(not start date)
OR
(not end date)
)
你如何 "fixed" 它,但通过在末尾添加额外的 "AND",你得到
SELECT events FROM events
WHERE
userID = :userID
AND (not start date)
OR (not end date)
AND userID = :userID
与
相同SELECT events FROM events
WHERE
(
userID = :userID
AND
(not start date)
)
OR
(
(not end date)
AND
userID = :userID
)
以迂回的方式做你想做的事...
问题出在您的 or
语句上。您的查询当前如下所示:
where relationship_condition AND start_date_condition OR end_date_condition
在操作的逻辑顺序中,AND
s 在 OR
s 之前执行,所以这等同于:
where (relationship_condition AND start_date_condition) OR end_date_condition
这意味着任何与您的 end_date_condition
匹配的记录都将被返回,无论它们是否与 relationship_condition
匹配。为了纠正这个问题,您需要正确分组您的 OR
条件,因此它看起来像这样:
where relationship_condition AND (start_date_condition OR end_date_condition)
因此,您的代码应如下所示:
$pets= Auth::user()->events()
->where(function ($query) use ($myYear, $myMonth, $myDay) {
return $query
->where(function ($query) use ($myYear, $myMonth, $myDay) {
return $query
->whereYear('start_date', '=', $myYear)
->whereMonth('start_date', '=', $myMonth)
->whereDay('start_date', '!=', $myDay);
})
->orWhere(function ($query) use($myYear, $myMonth, $myDay) {
return $query
->whereYear('end_date', '=', $myYear)
->whereMonth('end_date', '=', $myMonth)
->whereDay('end_date', '!=', $myDay);
});
})
->get();