我想在三个模型之间建立关系。我的模型是
用户
-- 数据库结构
id
name
---
图书
-- 数据库结构
id
name
书架
-- 数据库结构
id
name
1:用户有很多书,书属于很多用户
2:用户的书属于一个书架,用户的书架有很多书。
如何定义这三个模型之间的关系?我正在构建一个类似于 Goodreads 的应用程序。
1:用户有很多书,书属于很多用户
User有Many To Many关系_Book
// User model
public function books()
{
return $this->belongsToMany(Book::class, 'book_user');
}
Book有Many To Many关系_User
// Book model
public function users()
{
return $this->belongsToMany(User::class, 'book_user');
}
2:用户的书属于很多书架,书架有很多书。
Book有Many To Many关系_Bookshelf
// Book model
public function bookshelves()
{
return $this->belongsToMany(Bookshelf::class, 'book_bookshelf');
}
Bookshelf有Many 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') |
你的and之间有many to many关系,你的Userand之间Book也有many to many关系。BookBookShelf
这种类型的关系由pivot幕后的表管理,因此您将需要两个数据透视表。
用户和书之间的枢轴
php artisan make:migtration create_book_user_table
public function up()
{
Schema::create('book_user', function (Blueprint $table) {
$table->id();
$table->timestamps();
$table->foreignId('user_id')->constrained();
$table->foreignId('book_id')->constrained();
});
}
书和书架之间的枢轴
php artisan make:migtration create_book_book_shelf_table
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
让我们从第一个任务开始:
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 的书籍中过滤选择