2016-03-07 2 views
1

Я пытаюсь сделать многие-ко-многим дб отношений в моем веб-сайте, чтобы «Student» оба «университеты» и «майоры», как многие-ко-многим:Laravel неожиданно изменил имя моей таблицы?

class Student extends Model 
{ 
    protected $table = 'students'; 
    protected $fillable = ['username','password','email','degree','avatar','description']; 

    public function universities() 
    { 
     return $this->belongsToMany('App\University'); 
    } 

    public function majors() 
    { 
     return $this->belongsToMany('App\Major'); 
    } 
} 

и я тоже созданные модели и файлы миграции, и create_student_university_table.php и create_student_major_table.php.

Но при создании нового ученика, ужасно странная ошибка:

SQLSTATE [42S02]: Base таблицы или просмотреть не найдено: 1146 Таблица 'ozudb.major_student' не существует

это так странно для двух аспектов:

  1. University вещь работает отлично, но это не будет работать для Major даже они точно такой же процесс
  2. Я никогда не набирал ни одной вещи, как major_student! Файл миграции создает таблицу student_major. Я даже искал ключевые слова major_student и не нашел результата во всех моих файлах.

Этот странный вопрос разрушил мой вечер - все еще борется. А вот что происходит при создании нового студента:

public function postStudentRegister(Request $request) 
    { 
     \Auth::login("student",$this->createStudent($request->all())); 

     // store student_university and student_major pairs into table 
     $student = Student::where('username',$request->username)->first(); 
     $uniarr = []; 
     $majorarr = []; 

     $arr = explode(',', $request->universities); 
     $arrLen = sizeof($arr); 
     for($i=0;$i<$arrLen;$i++) { 
      array_push($uniarr, University::where('name',$arr[$i])->first()->id); 
     }; 
     $student->universities()->attach($uniarr); 

     $arr = explode(',', $request->majors); 
     $arrLen = sizeof($arr); 
     for($i=0;$i<$arrLen;$i++) { 
      array_push($majorarr, Major::where('name',$arr[$i])->first()->id); 
     }; 
     $student->majors()->attach($majorarr); 

     return redirect('student/regis-success'); 

    } 

Ошибка заинтересовавшись последней второй линии, $student->majors()->attach($majorarr);

Laravel пожалуйста, почему вы изменить свое имя таблицы?

ответ

1

Причину Laravel ищет major_students вместо student_major заключается в том, что, когда laravel динамически запрашивает отношения многих и многих, он выбирает две модели, которые являются Student и Major, и проверяет, какая первая буква в алфавитном порядке на первом месте, поэтому в этом случае M сначала является первым , Он присоединится к двум моделям (т. Е. С символом подчеркивания), который является майором и учеником (как я уже сказал, «М»), и строчными буквами как major_student.

Так вот почему вы видите эту ошибку.

Чтобы заставить Laravel использовать свое собственное имя пользовательской таблицы вы можете передать второй аргумент в вашу функцию belongsToMany как этот

public function universities() 
{ 
    return $this->belongsToMany('App\University','student_major'); 
} 

public function majors() 
{ 
    return $this->belongsToMany('App\Major', 'student_major'); 
} 

И к тому же это бонус на ваш вопрос.

Предвидя проблемы с запросом N + 1 с кодом в контроллере. Предложение foreach и where приведет к нескольким вызовам вашей базы данных, которые неэффективны.

public function postStudentRegister(Request $request) 
{ 
    \Auth::login("student",$this->createStudent($request->all())); 

    // store student_university and student_major pairs into table 
    $student = Student::where('username',$request->username)->first(); 
    $uniarr = []; 
    $majorarr = []; 

    $arr = explode(',', $request->universities); 
    $arrLen = sizeof($arr); 
    for($i=0;$i<$arrLen;$i++) { 
     array_push($uniarr, $arr[$i]); 
    }; 

    // This will get all the ids of the universities with names in the $uniarr thereby preventing several calls to the database; 
    $uniIdList = University::whereIn('name',$uniarr)->lists('id')->all() 
    $student->universities()->attach($uniIdList); 

    $arr = explode(',', $request->majors); 
    $arrLen = sizeof($arr); 
    for($i=0;$i<$arrLen;$i++) { 
     array_push($majorarr, $arr[$i]); 
    }; 

    // This will get all the ids of the Major's with names in the $uniarr thereby preventing several calls to the database; 
    $majorIdList = Major::whereIn('name',$majorarr)->lists('id')->all(); 
    $student->majors()->attach($majorIdList); 

    return redirect('student/regis-success'); 

} 
+0

Amazing .. Я не могу больше поблагодарить –

+0

Anytime Stanley – oseintow

1

Необходимо использовать сводные таблицы для отношений many-to-many. Eloquent ищет major_student, который представляет собой сводную таблицу с двумя внешними ключами: major_id и student_id. Вам нужно создать миграцию и выполнить ее.

Вы говорите, что в любом месте вы не используете major_student слов, но вещь Eloquent автоматически использует таблицу. Например, это пытается код, чтобы использовать его:

$student->majors()->attach($majorarr); 

https://laravel.com/docs/5.0/eloquent#working-with-pivot-tables

Чтобы заставить Laravel использовать пользовательский именованные сводные таблицы можно использовать второй параметр:

return $this->belongsToMany('App\Major', 'student_major'); 
+0

Спасибо, вы ведете меня в правильном направлении! Но имя таблицы, которое использует Eloquent, кажется совершенно случайным. Должен ли я просто удалить migrattion «create_student_major_table.php» и создать новую миграцию «create_major_student_table.php»? –

+0

Попробуйте откат, измените имя таблицы на «major_student» и снова выполните миграцию. Кроме того, можете ли вы отправить свои миграции, пожалуйста? Кроме того, вы можете заставить Laravel использовать пользовательский псевдоним. –

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