Laravel意外地改变了我的桌面名字?

时间:2016-03-07 12:38:23

标签: php laravel eloquent

我正试图在我的网站上建立多对多的数据库关系,让“学生”同时拥有“大学”和“专业”这两者:

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.phpcreate_student_major_table.php

但是在创建新学生时,发生了一个非常奇怪的错误:

  

SQLSTATE [42S02]:未找到基表或视图:1146表'ozudb.major_student'不存在

两个方面很奇怪:

  1. University内容非常有效,但即使它们完全相同,它也无法用于Major
  2. 我从来没有输入像major_student这样的东西!迁移文件生成student_major表。我甚至搜索了关键字major_student,但在我的所有文件中都没有找到结果。
  3. 这个奇怪的问题毁了我的晚上 - 仍然在挣扎。 以下是创建新学生时会发生的事情:

    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拜托,为什么要更改我的表名?

2 个答案:

答案 0 :(得分:1)

您需要为many-to-many关系使用数据透视表。 Eloquent正在寻找major_student,这是一个包含两个外键的数据透视表:major_idstudent_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');

答案 1 :(得分:1)

laravel寻找major_students而不是student_major的原因是,当laravel动态查询多对多关系时,它会选择Student和Major这两个模型,并按字母顺序检查哪一个字母首先出现所以在这种情况下,M是主要的第一。它将加入两个模型(即带有下划线),即Major和学生(正如我所说&#34; M&#34;第一个)并将它们作为major_student小写。

这就是你看到错误的原因。

要强制laravel使用您自己的自定义表名,您可以将第二个参数传递给belongsToMany函数,如下所示

    <activity
        android:name=".activities.ProtocolActivity"
        android:label="@string/title_activity_protocols"
        android:parentActivityName=".activities.InformationActivity"
        tools:targetApi="jelly_bean">
        <meta-data
            android:name="android.support.PARENT_ACTIVITY"
            android:value=".activities.InformationActivity" />
    </activity>

此外,这是对你问题的奖励。

预计控制器中的代码会出现N + 1个查询问题。 foreach和where子句将导致对数据库的多次调用,这是无效的。

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

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