Php 基于关系的Laravel选择模型

Php 基于关系的Laravel选择模型,php,mysql,laravel,eloquent,Php,Mysql,Laravel,Eloquent,我正在开发一个图书馆应用程序,我想创建一个功能,用户可以将一本书出租给客户。但是,我希望现在租出去的书在租出去另一本书时不会显示在选择框中。 我已经查阅了几篇关于这方面的文章,但无法真正制定出解决方案,因此我很乐意得到任何帮助。 这个想法是,当一本书设置了属性“maxreturndate”时,它不会显示 检查输出控制器: <?php namespace App\Http\Controllers; use Illuminate\Http\Request;

我正在开发一个图书馆应用程序,我想创建一个功能,用户可以将一本书出租给客户。但是,我希望现在租出去的书在租出去另一本书时不会显示在选择框中。 我已经查阅了几篇关于这方面的文章,但无法真正制定出解决方案,因此我很乐意得到任何帮助。 这个想法是,当一本书设置了属性“maxreturndate”时,它不会显示

检查输出控制器:

    <?php

    namespace App\Http\Controllers;

    use Illuminate\Http\Request;
    use App\CheckedOut;
    use App\Book;
    use App\Reader;



    class CheckedOutController extends Controller
    {
        /**
         * Display a listing of the resource.
         *
         * @return \Illuminate\Http\Response
         */
        public function index()
        {
            $checkedOuts = CheckedOut::with(['book', 'reader'])->get();

            return view('checkedouts/index', compact('checkedOuts'));
        }

        /**
         * Show the form for creating a new resource.
         *
         * @return \Illuminate\Http\Response
         */
        public function create()
        {
            $books = Book::all();
            $readers = Reader::all();

            return view('checkedouts/create', compact('books','readers'));
        }

        /**
         * Store a newly created resource in storage.
         *
         * @param  \Illuminate\Http\Request  $request
         * @return \Illuminate\Http\Response
         */
        public function store(Request $request)
        {
            $validatedData = $request->validate([
                'book_id' => 'required',
                'reader_id' => 'required',
                'maxreturndate' => 'required|date',
                'returndate' => 'nullable',
                ]);

                $checkedOut = CheckedOut::create($validatedData);

                return redirect('checkedouts')->with('success', 'Buch wurde erfolgreich verliehen!');
        }

        /**
         * Display the specified resource.
         *
         * @param  int  $id
         * @return \Illuminate\Http\Response
         */
        public function show($id)
        {
            //
        }

        /**
         * Show the form for editing the specified resource.
         *
         * @param  int  $id
         * @return \Illuminate\Http\Response
         */
        public function edit($id)
        {
            //
        }

        /**
         * Update the specified resource in storage.
         *
         * @param  \Illuminate\Http\Request  $request
         * @param  int  $id
         * @return \Illuminate\Http\Response
         */
        public function update(Request $request, $id)
        {
            //
        }

        /**
         * Remove the specified resource from storage.
         *
         * @param  int  $id
         * @return \Illuminate\Http\Response
         */
        public function destroy($id)
        {
            //
        }
    }
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateCheckedOutsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('checked_outs', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->bigInteger('book_id')->unsigned();
            $table->foreign('book_id')->references('id')->on('books')->onDelete('cascade');
            $table->bigInteger('reader_id')->unsigned();
            $table->foreign('reader_id')->references('id')->on('readers')->onDelete('cascade');
            $table->date('maxreturndate');
            $table->date('returndate')->nullable();
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('checked_outs');
    }
}
读者:

public function checkedOut()
    {
        return $this->belongsTo(CheckedOut::class);
    }
签出:

public function book(){
    return $this->belongsTo(Book::class);

}

public function reader(){
    return $this->belongsTo(Reader::class);

}

我的建议是用一个新的方法设置
书籍
读者
。现在,您的模型可以如下所示:

<?php
namespace App;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\Pivot;

class Book extends Model
{
    public function readers()
    {
        return $this
            ->belongsToMany(\App\Reader::class, 'checked_outs')
            ->using(\App\Checkout::class)
            ->withPivot(['returndate', 'maxreturndate']);
    }
}

class Reader extends Model
{
    public function books()
    {
        return $this
            ->belongsToMany(\App\Book::class, 'checked_outs')
            ->using(\App\Checkout::class)
            ->withPivot(['returndate', 'maxreturndate']);
    }
}

class Checkout extends Pivot
{
    // this should be named `book_reader` but we override it here
    $table = "checked_outs";

    $dates = [
        "maxreturndate",
        "returndate",
    ];
}
public function store(Request $request)
{
    $reader = Reader::find($request->reader_id);
    $reader
        ->books()
        ->attach(
            $request->book_id,
            ["returndate" => Carbon\Carbon::now()->addDays(7)]
        );
}
“借阅”一本书可能是这样的:

<?php
namespace App;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\Pivot;

class Book extends Model
{
    public function readers()
    {
        return $this
            ->belongsToMany(\App\Reader::class, 'checked_outs')
            ->using(\App\Checkout::class)
            ->withPivot(['returndate', 'maxreturndate']);
    }
}

class Reader extends Model
{
    public function books()
    {
        return $this
            ->belongsToMany(\App\Book::class, 'checked_outs')
            ->using(\App\Checkout::class)
            ->withPivot(['returndate', 'maxreturndate']);
    }
}

class Checkout extends Pivot
{
    // this should be named `book_reader` but we override it here
    $table = "checked_outs";

    $dates = [
        "maxreturndate",
        "returndate",
    ];
}
public function store(Request $request)
{
    $reader = Reader::find($request->reader_id);
    $reader
        ->books()
        ->attach(
            $request->book_id,
            ["returndate" => Carbon\Carbon::now()->addDays(7)]
        );
}
当一本书设置了属性“maxreturndate”时,它不会显示

由于您没有在迁移中指定,我将在这里假设您的
books
表中有一个
maxreturndate
null字段,那么您应该能够在需要“未租用”图书列表时创建一个

下面是一个创建
notrendered
范围的示例:

// in your Book model define the local scope
public function scopeNotRented($query){
    return $query->whereNotNull('maxreturndate');
}

// in the create method of your controller
public function create()
{
    $books = Book::notRented()->get();
    $readers = Reader::all();

    return view('checkedouts/create', compact('books','readers'));
}

书与读者之间的关系是什么?看起来像是将签出的
作为数据透视表的多对多关系?这只是一对一关系,我不想这次把它弄得太复杂。基本上一个读者一次可以看一本书。你能用这三个模型的关系信息更新这个问题吗?通过引入
CheckedOut
作为一个模型,并使其成为一个透视表(但不是真正的透视表),您已经使其变得比需要的更复杂了!我更新了它!很抱歉缺少信息。因此您的
阅读器
表有一个
签出id
列?谢谢!所以基本上我甚至不需要CheckedOut模型,对吗?但如果理解正确,我仍然可以使用CheckedOutController并将create函数放在那里?我还认为pivot表是由两个合并的表组成的,所以在本例中它将被称为books\u readers,但显然您也可以使用自定义名称?对不起,谢谢您提前回复!通常不需要为透视表创建模型。在上面的例子中,我使用它来转换日期属性,它可以帮助处理类似的事情。正如我上面提到的,透视表的默认名称是
book\u reader
,但是您可以覆盖它。谢谢!我设法更改了我的应用程序,但我现在不知道如何从索引页上的透视表输出数据。我已经用我的索引页更新了我的问题。你能帮我做最后一件事吗?使用
pivot
属性,例如
$book->pivot->returndate
。在“检索中间表列”下的文档中,我已经尝试了好几次,但我就是无法显示数据。我问了另一个问题,你能看一下吗@米肯32哦,你说得对,我在迁移中错过了。OP提到这本书将有一个属性。我将编辑我的答案以澄清这一点。
public function store(Request $request)
{
    $reader = Reader::find($request->reader_id);
    $reader
        ->books()
        ->attach(
            $request->book_id,
            ["returndate" => Carbon\Carbon::now()->addDays(7)]
        );
}
// in your Book model define the local scope
public function scopeNotRented($query){
    return $query->whereNotNull('maxreturndate');
}

// in the create method of your controller
public function create()
{
    $books = Book::notRented()->get();
    $readers = Reader::all();

    return view('checkedouts/create', compact('books','readers'));
}