2016-12-06 6 views
2
отношений

пользователя: отношенияОшибка при использовании hasMany. Я получаю не связанные объекты

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(), и я не знаю почему.

Может кто-нибудь помочь мне решить этот вопрос?

+1

Вы не могли бы показать соответствующие части схемы тоже? – Jite

+0

Привет, Jite, что вы подразумеваете под схемой? Связь базы данных? Один пользователь имеет N событий, одно событие принадлежит одному пользователю. Его соотношение 1: N. Событие имеет идентификатор пользователя в качестве поля – MartaGom

+0

У вас есть «миграция» для базы данных? Место, где вы создаете поля базы данных и соединения с внешними ключами между двумя таблицами. – Jite

ответ

1

Проблема с вашим заявлением or. Ваш запрос в настоящее время выглядит следующим образом:

where relationship_condition AND start_date_condition OR end_date_condition 

В логическом порядке операций, то AND s выполняется перед OR с, так что это эквивалентно:

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

Благодарим вас за помощь, сэр. Я понимаю и решаю свою проблему :) – MartaGom

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

Спасибо за вашу помощь :) – MartaGom

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

Как вы «фиксированной» это, но, добавив дополнительные «И» в конце концов, вы получите

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 
    ) 

, который делает то, что вы хотите, окольным путем ...

+0

Спасибо за помощь :) – MartaGom

Смежные вопросы