我正试图在我的网站上建立多对多的数据库关系,让“学生”同时拥有“大学”和“专业”这两者:
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]:未找到基表或视图:1146表'ozudb.major_student'不存在
两个方面很奇怪:
University
内容非常有效,但即使它们完全相同,它也无法用于Major
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拜托,为什么要更改我的表名?
答案 0 :(得分: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');
答案 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');
}