首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >基于关系的Laravel选择模型

基于关系的Laravel选择模型
EN

Stack Overflow用户
提问于 2020-03-10 20:21:12
回答 2查看 399关注 0票数 0

我正在开发一个库应用程序,我想要创建一个函数,用户可以在其中将一本书租给客户。但是,我希望现在租出去的书在租出另一本书时不会出现在选择框中。我已经看过几篇关于这方面的文章,但没有真正想出一个解决方案,所以我很乐意得到任何帮助。这样做的想法是,当一本书的属性是"maxreturndate“设置时,它就不会出现。

CheckedOutController:

代码语言:javascript
运行
复制
    <?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)
        {
            //
        }
    }

index.blade.php

代码语言:javascript
运行
复制
@extends('layout')


@section('title')
<title>Alle ausgeliehen Bücher</title>
@section('content')
<style>
  .uper {
    margin-top: 40px;
  }
</style>
<div class="uper">
  @if(session()->get('success'))
  <div class="alert alert-success">
    {{ session()->get('success') }}
  </div><br />
  @endif

  <table class="table table-hover">
    <thead>
      <tr>
        <td>ID</td>
        <td>Titel</td>
        <td>Verliehen an</td>
        <td>Verleihdatum</td>
        <td>Fällig am</td>
        <td>Zurückgebracht am</td>
        <td colspan="2">Funktionen</td>
      </tr>
    </thead>
    <tbody>
      @foreach($checkedOuts as $checkedOut)
      <tr>
        <td>{{$checkedOut->id}}</td>
        <td>{{$checkedOut->book->title}}</td>
        <td>{{$checkedOut->reader->name}}</td>
        <td>{{$checkedOut->created_at}}</td>
        <td >{{$checkedOut->maxreturndate}}</td>
        <td>{{$checkedOut->returndate}}</td>
        <td></td>

        <td><a href="{{ route('checkedouts.edit', $checkedOut->id)}}" class="btn btn-primary">Bearbeiten</a></td>
        <td><a href="{{ route('checkedouts.show', $checkedOut->id)}}" class="btn btn-primary">Anzeigen</a></td>
        <td>
          <form action="{{ route('checkedouts.destroy', $checkedOut->id)}}" method="post">
            @csrf
            @method('DELETE')
            <button class="btn btn-danger" type="submit">Löschen</button>
          </form>
        </td>
      </tr>
      @endforeach
    </tbody>
  </table>
  <div>
    @endsection

迁移:

代码语言:javascript
运行
复制
<?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');
    }
}

create.blade.php

代码语言:javascript
运行
复制
@extends('layout')


@section('title')
<title>Buch verleihen</title>
@section('stylesheets')
<script src="http://code.jquery.com/jquery-3.4.1.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/select2@4.0.13/dist/js/select2.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/select2@4.0.13/dist/css/select2.min.css" rel="stylesheet" />


@endsection
@section('content')
<style>
    .uper {
        margin-top: 40px;
    }
</style>
<div class="card uper">
    <div class="card-header">
        Buch verleihen
    </div>
    <div class="card-body">
        <form method="post" action="{{ route('checkedouts.store') }}">
            <div class="form-group">
                @csrf
                <label for="book_id">Buch:</label>
                <select name="book_id" class="form-control select2-single <!-- @error('book_id') is-invalid @enderror -->">
                    @foreach ($books as $book)
                    <option value="{{ $book->id }}">{{ $book->title }}</option>
                    @endforeach
                </select>
                @error('book_id')
                <div class="alert alert-danger">{{ $message }}</div>
                @enderror
            </div>

            <div class="form-group">
                <label for="reader_id">Verleihen an:</label>
                <select name="reader_id" class="form-control select2-single <!-- @error('reader_id') is-invalid @enderror -->">
                    @foreach ($readers as $reader)
                    <option value="{{ $reader->id }}">{{ $reader->name }}</option>
                    @endforeach
                </select>
                @error('reader_id')
                <div class="alert alert-danger">{{ $message }}</div>
                @enderror
            </div>

            <div class="form-group">
                <label for="maxreturndate">Zurückbringen bis:</label>
                <input type="date" class="form-control" name="maxreturndate" />
                @error('name')
                <div class="alert alert-danger">{{ $message }}</div>
                @enderror
            </div>

            <button type="submit" class="btn btn-primary">Verleihen</button>
        </form>
    </div>
</div>
<script type="text/javascript">
    $(".select2-single").select2();
</script>

@endsection

三个模型之间的关系:

书籍:

代码语言:javascript
运行
复制
public function checkedOut(){
    return $this->hasOne(CheckedOut::class);
}

读者:

代码语言:javascript
运行
复制
public function checkedOut()
    {
        return $this->belongsTo(CheckedOut::class);
    }

CheckedOut:

代码语言:javascript
运行
复制
public function book(){
    return $this->belongsTo(Book::class);

}

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

}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-03-10 20:56:24

我的建议是用一个BooksReaders设置一个多对多关系。现在,你的模特可能看起来是这样的:

代码语言:javascript
运行
复制
<?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",
    ];
}

我有创建了一个枢轴模型,这是不必要的,但允许您直接操作pivot表,并将额外的属性自动转换为dates。这是否有用是一个意见问题。您应该将checked_outs表重命名为book_reader,这是Laravel希望用于支点表的命名约定。

获取未结帐的书籍非常简单,如下所示,使用方法检查是否没有关系。

代码语言:javascript
运行
复制
public function create()
{
    $books = Book::doesntHave("readers")->get();
    $readers = Reader::all();

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

“退房”一本书可能是这样的:

代码语言:javascript
运行
复制
public function store(Request $request)
{
    $reader = Reader::find($request->reader_id);
    $reader
        ->books()
        ->attach(
            $request->book_id,
            ["returndate" => Carbon\Carbon::now()->addDays(7)]
        );
}
票数 0
EN

Stack Overflow用户

发布于 2020-03-10 22:44:02

当一本书设置了属性"maxreturndate“时,它就不会出现。

由于您在迁移中没有指定,所以我在这里假设您的books表中有一个maxreturndate可空字段,那么当您想要您的“未租”书籍列表时,您应该能够简单地创建一个局部范围

下面是一个创建notRented作用域的示例:

代码语言:javascript
运行
复制
// 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'));
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60625346

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档