使用hasMany时出错。我得到了非相关的对象

时间:2016-12-06 08:56:58

标签: php laravel-4 eloquent relationship

用户关系:

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个用户。我需要在->where("user_id", Auth::user()->id)之前添加-get(),我不知道为什么。

有人可以帮我解决这个问题吗?

3 个答案:

答案 0 :(得分:1)

你没有保留$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();

答案 1 :(得分:1)

如何解决:在mySQL中(我假设你正在使用,如果它是Lavavel)只需打开"通用日志"。这里有一个相当不错的StackOverflow如何做到这一点:How to enable MySQL Query Log?

这将记录对MySQL的所有调用,并且您将能够看到该构造。

下一步是猜测:您可能会发现查询最终为:

SELECT events FROM events
    WHERE
      userID = :userID 
      AND (not start date)
      OR (not end date)

因为ANDs的评估优先级较高(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)
      )

你是如何修复"它,但通过添加额外" 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 
      )

以迂回的方式做你想要的......

答案 2 :(得分:1)

问题在于您的or声明。您的查询目前如下所示:

where relationship_condition AND start_date_condition OR end_date_condition

按照逻辑操作顺序,ANDOR之前执行,因此这相当于:

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();