如何使用没有模型的列将数据插入数据透视表?

时间:2017-06-25 09:00:24

标签: laravel-5.4

我正在学习laravel数据透视表,这就是我正在做的事情。我有一个学生和学科模型,有很多很多关系。在我的数据透视表中,我已经包含了test1,test2和test3的列,以便我可以使用它来存储每个主题的学生分数。这些是我的模特

class Student extends Model
{
    protected $guarded = ['id'];

    public function subjects()
    {
        return $this->belongsToMany(Subject::class);
    }
}

class Subject extends Model
{
    protected $guarded = ['id'];

    public function students()
    {
        return $this->belongsToMany(Student::class);
    }
}

这是我的迁移

public function up()
{
    Schema::create('subjects', function (Blueprint $table) {
        $table->increments('id');
        $table->string('name')->unique();
        $table->timestamps();
    });

    Schema::create('student_subject', function (Blueprint $table) {
        $table->integer('student_id');
        $table->integer('subject_id');
        $table->primary(['student_id', 'subject_id']);
        $table->integer('test1')->nullable();
        $table->integer('test2')->nullable();
        $table->integer('test3')->nullable();
    });
}

这对我来说都很复杂。创建学生记录后,用户将被重定向到注册页面,为学生选择科目。

这是我的StudController @ store

public function store(Request $request)
{
    $student = Student::create(request()->all());

    Session::flash('status', "New student's record was added successfully");
    Session::put('firstname', request('firstname'));
    Session::put('lastname', request('lastname'));
    Session::put('student_id', $student->id);
    Session::put('class', $student->class_admitted);

    return redirect('/enroll');
}

这是报名表

<form class="form-horizontal" role="form" method="POST" action="/enroll">
{{ csrf_field() }}

<input type="" name="student_id" value="{{ Session::get('student_id')}}" hidden>

<div class="col-md-6 form-group subjectList">
    <ul>
        @foreach ($subjects as $subject)
            <li><label class="checkbox-inline"><input type="checkbox" name="subject_id[]" value="{{ $subject->id }}">  {{ ucwords($subject->name) }}</label></li>
        @endforeach
    </ul>
</div>

<div class="form-group">
    <div class="col-md-6 col-md-offset-4">
        <button type="submit" class="btn btn-primary">
            Enroll
        </button>
    </div>
</div>
</form>

这是我的EnrollController @ store

public function store(Request $request)
{
    //dd($request);

    $student = request('student_id');

    foreach ($request->input('subject_id') as $subject) {
        $student->subjects()->attach($subjects);
    }
}

我对如何插入数据透视表感到困惑。

1 个答案:

答案 0 :(得分:2)

您可以在attach()方法中添加数组,如下所示:

->attach($subjectId, ['test1' => 1, 'test2' => 2]);

attach()方法将在数据透视表中创建条目,将添加其他属性。

您还可以将一系列主题传递给attach(),如下所示:

->attach([1 => ['test1' => 1, 'test2' => 2], 2 => ['test1' => 3, 'test2' => 4]]);

当您需要更新数据透视数据时,可以使用sync()

据我所知,除了主题外,你的表单中没有任何内容,所以我假设你想稍后更新数据透视数据。

此外,您可能希望在学生和科目上添加一些额外的验证。

public function store(Request $request)
{
    // making sure student exists
    $student = Student::findOrFail(request('student_id'));

    $subjectIds = Subject::whereIn('id', $request->input('subject_id', []))
        ->get()
        ->pluck('id')
        ->all();

    $student->subjects()->attach($subjectIds);

    // you can also use sync here, that way it will add new subjects, keep the ones that already exist (and are posted) and remove subjects not in post
    // $student->subjects()->sync($subjectIds);
}