0

我想在三个模型之间建立关系。我的模型是

用户

-- 数据库结构

  id

  name

  ---

图书

-- 数据库结构

  id

  name

书架

-- 数据库结构

  id

  name

1:用户有很多书,书属于很多用户

2:用户的书属于一个书架,用户的书架有很多书。

如何定义这三个模型之间的关系?我正在构建一个类似于 Goodreads 的应用程序。

4

3 回答 3

0

1:用户有很多书,书属于很多用户

  • UserMany To Many关系_Book
    • // User model
      public function books()
      {
          return $this->belongsToMany(Book::class, 'book_user');
      }
      
  • BookMany To Many关系_User
    • // Book model
      public function users()
      {
          return $this->belongsToMany(User::class, 'book_user');
      }
      

2:用户的书属于很多书架,书架有很多书。

  • BookMany To Many关系_Bookshelf
    • // Book model
      public function bookshelves()
      {
          return $this->belongsToMany(Bookshelf::class, 'book_bookshelf');
      }
      
  • BookshelfMany To Many关系_Book
    • // Bookshelf model
      public function books()
      {
          return $this->belongsToMany(Book::class, 'book_bookshelf');
      }
      

你需要两个数据透视表。

book_user

柱子 移民
ID $table->id()
book_id $table->foreignId('book_id')->constrained('books')
用户身份 $table->foreignId('user_id')->constrained('users')

book_bookshelf

柱子 移民
ID $table->id()
book_id $table->foreignId('book_id')->constrained('books')
书架_id $table->foreignId('bookshelf_id')->constrained('bookshelves')
于 2021-02-12T13:54:09.917 回答
0

你的and之间有many to many关系,你的Userand之间Book也有many to many关系。BookBookShelf

这种类型的关系由pivot幕后的表管理,因此您将需要两个数据透视表。

用户和书之间的枢轴

  1. 创建您的迁移
php artisan make:migtration create_book_user_table
  1. 定义你的关系
public function up()
{
    Schema::create('book_user', function (Blueprint $table) {
        $table->id();
        $table->timestamps();
        $table->foreignId('user_id')->constrained();
        $table->foreignId('book_id')->constrained();
    });
}

书和书架之间的枢轴

  1. 创建您的迁移
php artisan make:migtration create_book_book_shelf_table
  1. 定义你的关系
public function up()
{
    Schema::create('book_user', function (Blueprint $table) {
        $table->id();
        $table->timestamps();
        $table->foreignId('book_id')->constrained();
        $table->foreignId('book_shelf_id')->constrained();
    });
}

通过创建数据透视表,您可以将关系添加到模型中。

用户

public function books()
{
    return $this->belongsToMany(Book::class);
}

public function users()
{
    return $this->belongsToMany(User::class);
}

public function bookshelves()
{
    return $this->belongsToMany(BookShelf::class);
}

书架

public function books()
{
    return $this->belongsToMany(Book::class);
}

现在你有了你的关系,你可以在你的User. 举个例子:

Route::get('/', function () {
    $user = User::where('id', 1)->with(['books', 'books.bookshelves'])->first();
    return view('user', compact('user'));
});

用户刀片.php

<h3>{{ $user->name }}</h3>

<h4>Books</h4>
@foreach ($user->books as $book)
    <h5>{{ $book->name }}</h5>
    <p>Can be found on @choice('shelf|shelves', $book->bookShelves()->count())</p>
    @foreach ($book->bookShelves as $shelf)
        <li>{{ $shelf->name }}</li>
    @endforeach
@endforeach

上面将遍历每个Book$user然后遍历BookShelves与之Book相关的每个。

更新

如果 aBook只能属于 one Bookshelf,则需要更改books表。

public function up()
{
    Schema::create('books', function (Blueprint $table) {
        $table->id();
        $table->timestamps();
        $table->string('name');
        $table->foreignId('bookshelf_id')->constrained('book_shelves');
    });
}

您还需要更改Book模型上的关系:

public function bookshelf()
{
    return $this->belongsTo(BookShelf::class);
}

这种方式aBook现在只能属于one Bookshelf

如果 aUser只能有one Bookshelf,您需要再次更改您的book_shelves表格:

public function up()
{
    Schema::create('book_shelves', function (Blueprint $table) {
        $table->id();
        $table->timestamps();
        $table->string('name');
        $table->foreignId('user_id')->constrained();
    });
}

然后将关系添加到您的User.

public function bookshelf()
{
    return $this->hasOne(BookShelf::class);
}

然后,您应该能够直接访问Bookshelffor a User

$user->bookshelf->books
于 2021-02-12T14:11:52.480 回答
0

让我们从第一个任务开始:

1:用户有很多书,书属于很多用户

在这种情况下,它是多对多关系。要实现此设置,您需要像这样的用户表:

用户:id、name、someotherdata

那么你需要书桌:

书籍:ID、姓名、书籍数据

然后您需要第三个表将它们多对多连接:

users_books:id、book_id、user_id

在这种情况下,当您需要属于某个用户的所有书籍时,您可以从 users_books 中选择 user_id=someuserid 并将其与书籍表连接,您将收到属于某个用户的所有书籍。

反之亦然,您可以接收拥有某些特定书籍的所有用户。

2:用户的书属于一个书架,用户的书架有很多书。

为此,您必须创建表书架:id、name

并将外键添加到书表作为 bookshelf_id

然后你的书桌将如下所示:

书籍:id、名称、bookdata、bookshelf_id。

因此,当您需要从书架上获取所有书籍时,只需从 bookshelf_id = someid 的书籍中过滤选择

于 2021-02-12T17:21:03.413 回答