Table of Contents
Association
Define the reverse relationship
One To Many
Define reverse association
Many To Many
Reverse association Relationship
Retrieve the column value of the intermediate table
Has Many Through
Polymorphic Relations
Retrieve polymorphic relationships
Many-to-many polymorphic association
Association relationship query
查询关系存在性
预加载
带约束的预加载
关联模型插入" >关联模型插入
save方法
保存多个关联模型
save方法和多对多关联
create方法
更新 “Belongs To” 关系
Many to Many 关系
更新中间表(关联表)字段
Home Backend Development PHP Tutorial Laravel framework - Detailed introduction to the advanced parts of EloquentORM

Laravel framework - Detailed introduction to the advanced parts of EloquentORM

Mar 21, 2017 am 09:18 AM

Association

One To One
Assume that Usermodel is associated with the Phone model. To define such an association, you need to define a phone method in the User model, which returns An association defined by the hasOne method

1

2

3

4

5

6

7

8

9

<?phpnamespace App;use Illuminate\Database\Eloquent\Model;class User extends Model{

    /**

     * Get the phone record associated with the user.

     */

    public function phone()

    {

        return $this->hasOne(&#39;App\Phone&#39;);

    }

}

Copy after login

The first parameter of the hasOne method is the model to be associated. After it is defined, you can use the following syntax to query the associated attributes

1

$phone = User::find(1)->phone;

Copy after login

Eloquent will assume the association The foreign key is based on the model name, so the Phone model will automatically use the user_id field as the foreign key, which can be overridden using the second and third parameters

1

return $this->hasOne(&#39;App\Phone&#39;, &#39;foreign_key&#39;);return $this->hasOne(&#39;App\Phone&#39;, &#39;foreign_key&#39;, &#39;local_key&#39;);

Copy after login

Define the reverse relationship

After defining the above model, you can use the User model to obtain the Phone model. Of course, you can also obtain the corresponding User through the Phone model. This uses the belongsTo method

1

2

3

4

5

6

7

8

9

10

11

<?phpnamespace App;use Illuminate\Database\Eloquent\Model;class Phone extends Model{

    /**

     * Get the user that owns the phone.

     */

    public function user()

    {

        return $this->belongsTo(&#39;App\User&#39;);        // return $this->belongsTo(&#39;App\User&#39;, &#39;foreign_key&#39;);

        // return $this->belongsTo(&#39;App\User&#39;, &#39;foreign_key&#39;, &#39;other_key&#39;);

 

    }

}

Copy after login

One To Many

Suppose there is a post with a lot of associated comment information. In this case, a one-to-many association should be used, using the hasMany method

1

2

3

4

5

6

7

8

9

<?phpnamespace App;use Illuminate\Database\Eloquent\Model;class Post extends Model{

    /**

     * Get the comments for the blog post.

     */

    public function comments()

    {

        return $this->hasMany(&#39;App\Comment&#39;);

    }

}

Copy after login

Query operation

1

2

3

4

$comments = App\Post::find(1)->comments;

foreach ($comments as $comment) {    //}

 

$comments = App\Post::find(1)->comments()->where(&#39;title&#39;, &#39;foo&#39;)->first();

Copy after login

Define reverse association

Reverse association also uses the belongsTo method, refer to the One To One section.

1

2

$comment = App\Comment::find(1);

echo $comment->post->title;

Copy after login

Many To Many

Many-to-many association is more complicated to implement than hasOne and hasMany because there is an additional intermediate table.

Consider a scenario where a user can belong to multiple roles, and a role can also belong to multiple users. This introduces three tables: users, roles, role_user. The role_user table is a related table and contains two fields user_id and role_id.

Many-to-many association requires the belongsToMany method

1

2

3

4

5

6

7

8

9

10

11

12

13

14

<?phpnamespace App;use Illuminate\Database\Eloquent\Model;class User extends Model{

    /**

     * The roles that belong to the user.

     */

    public function roles()

    {

        // 指定关联表

        // return $this->belongsToMany(&#39;App\Role&#39;, &#39;role_user&#39;);

        // 指定关联表,关联字段

        // return $this->belongsToMany(&#39;App\Role&#39;, &#39;role_user&#39;, &#39;user_id&#39;, &#39;role_id&#39;);

 

        return $this->belongsToMany(&#39;App\Role&#39;);

    }

}

Copy after login

The above defines that a user belongs to multiple roles. Once the relationship is established, you can query it

1

2

user = App\User::find(1);

foreach ($user->roles as $role) {    //}$roles = App\User::find(1)->roles()->orderBy(&#39;name&#39;)->get();

Copy after login

Reverse association Relationship

The reverse relationship is implemented the same as the forward relationship

1

2

3

4

5

6

7

8

9

<?phpnamespace App;use Illuminate\Database\Eloquent\Model;class Role extends Model{

    /**

     * The users that belong to the role.

     */

    public function users()

    {

        return $this->belongsToMany(&#39;App\User&#39;);

    }

}

Copy after login

Retrieve the column value of the intermediate table

For many-to-many relationships, an intermediate table is introduced, so There needs to be a way to query the column values ​​of the intermediate table, such as the time when the relationship was established, etc. Use the pivot attribute to query the intermediate table

1

2

3

4

5

$user = App\User::find(1);

 

foreach ($user->roles as $role) {

    echo $role->pivot->created_at;

}

Copy after login

The above code accesses the created_at field of the intermediate table.

Note that by default, the keys of the subsequent models can be accessed through the pivotobject. If the intermediate table contains additional attributes, you need to use the withPivot method when specifying the association. Explicitly specify the column name

1

return $this->belongsToMany(&#39;App\Role&#39;)->withPivot(&#39;column1&#39;, &#39;column2&#39;);

Copy after login

Has Many Through

This relationship is relatively powerful. Suppose there is a scenario: the Country model contains multiple User models, and each User model contains Multiple Post models, that is to say, there are many users in a country, and these users have many posts. We want to query all posts in a certain country. How to achieve this? This uses the Has Many Through relationship

1

2

3

4

5

6

countries    id - integer

    name - stringusers    id - integer

    country_id - integer

    name - stringposts    id - integer

    user_id - integer

    title - string

Copy after login

As you can see, the posts table does not directly contain country_id, but it establishes a relationship with the countries table through the users table.

Using the Has Many Through relationship

1

2

3

4

5

6

7

8

9

10

11

namespace App;

 

use Illuminate\Database\Eloquent\Model;class Country extends Model{    /**

     * Get all of the posts for the country.

     */

    public function posts()

    {        // return $this->hasManyThrough(&#39;App\Post&#39;, &#39;App\User&#39;, &#39;country_id&#39;, &#39;user_id&#39;);

 

        return $this->hasManyThrough(&#39;App\Post&#39;, &#39;App\User&#39;);

    }

}

Copy after login

The first parameter of the method hasManyThrough is the name of the model we wish to access, and the second parameter is the intermediate model name.

1

2

3

4

5

6

HasManyThrough hasManyThrough(

    string $related,

    string $through,

    string|null $firstKey = null,

    string|null $secondKey = null,

    string|null $localKey = null)

Copy after login

Polymorphic Relations

Polymorphic relations allow the same model to belong to multiple different models using one association. Assume such a scenario, we have a post table and In a comment table, users can like both posts and comments. How to deal with this situation?

The table structure is as follows

1

2

3

4

5

6

7

posts    id - integer

    title - string

    body - textcomments    id - integer

    post_id - integer

    body - textlikes    id - integer

    likeable_id - integer

    likeable_type - string

Copy after login

As you can see, we use the likeable_type field in the likes table to determine whether the record likes a post or a comment. With the table structure in place, it is time to define the model.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

<?php

 

namespace App;

 

use Illuminate\Database\Eloquent\Model;class Like extends Model{    /**

     * Get all of the owning likeable models.

     */

    public function likeable()

    {        return $this->morphTo();

    }

}class Post extends Model{    /**

     * Get all of the product&#39;s likes.

     */

    public function likes()

    {        return $this->morphMany(&#39;App\Like&#39;, &#39;likeable&#39;);

    }

}class Comment extends Model{    /**

     * Get all of the comment&#39;s likes.

     */

    public function likes()

    {        return $this->morphMany(&#39;App\Like&#39;, &#39;likeable&#39;);

    }

}

Copy after login

By default, the type of likeable_type is the complete name of the associated model, such as App\Post and App\Comment here.

Normally we may use a custom value to identify the associated table name. Therefore, we need to customize this value. We need to register the association in the boot method of the project's service provider object. , for example, in the boot method of AppServiceProvider

1

2

use Illuminate\Database\Eloquent\Relations\Relation;Relation::morphMap([    &#39;posts&#39; => App\Post::class,

    &#39;likes&#39; => App\Like::class,]);

Copy after login

Retrieve polymorphic relationships

Access all likes of a post

1

2

$post = App\Post::find(1); 

foreach ($post->likes as $like) {    //}

Copy after login

Access a liked post or comment

1

2

$like = App\Like::find(1);  

$likeable = $like->likeable;

Copy after login

In the above example, the returned likeable will return posts or comments based on the type of the record.

Many-to-many polymorphic association

Many-to-many association uses the methods morphToMany and morphedByMany, there will be no more nonsense here

Association relationship query

In Eloquent, all relationships are defined using functions , and related instances can be obtained without executing related queries. Suppose we have a blog system, and the User model is associated with many Post models:

1

2

3

4

5

/**

 * Get all of the posts for the user.

 */public function posts()

{   return $this->hasMany(&#39;App\Post&#39;);

}

Copy after login

You can query the association as follows and add additional constraints

1

$user = App\User::find(1);$user->posts()->where(&#39;active&#39;, 1)->get();

Copy after login

If not needed Add constraints to the associated attributes, which can be accessed directly as attributes of the model. For example, in the above example, we can use the following method to access User's Post

1

$user = App\User::find(1);foreach ($user->posts as $post) {    //}

Copy after login

动态的属性都是延迟加载的,它们只有在被访问的时候才会去查询数据库,与之对应的是预加载,预加载可以使用关联查询出所有数据,减少执行sql的数量。

查询关系存在性

使用has方法可以基于关系的存在性返回结果

1

2

3

// 检索至少有一个评论的所有帖子...$posts = App\Post::has(&#39;comments&#39;)->get();

// Retrieve all posts that have three or more comments...$posts = Post::has(&#39;comments&#39;, &#39;>=&#39;, 3)->get();

// Retrieve all posts that have at least one comment with votes...$posts = Post::has(&#39;comments.votes&#39;)->get();

Copy after login

如果需要更加强大的功能,可以使用whereHas和orWhereHas方法,把where条件放到has语句中。

1

2

3

// 检索所有至少存在一个匹配foo%的评论的帖子$posts = Post::whereHas(&#39;comments&#39;, function ($query) {   

$query->where(&#39;content&#39;, &#39;like&#39;, &#39;foo%&#39;);

})->get();

Copy after login

预加载

在访问Eloquent模型的时候,默认情况下所有的关联关系都是延迟加载的,在使用的时候才会开始加载,这就造成了需要执行大量的sql的问题,使用预加载功能可以使用关联查询出所有结果

1

2

3

4

5

6

7

8

9

<?phpnamespace App;use Illuminate\Database\Eloquent\Model;class Book extends Model{

    /**

     * Get the author that wrote the book.

     */

    public function author()

    {

        return $this->belongsTo(&#39;App\Author&#39;);

    }

}

Copy after login

接下来我们检索所有的书和他们的作者

1

2

3

4

$books = App\Book::all();

foreach ($books as $book) {   

echo $book->author->name;

}

Copy after login

上面的查询将会执行一个查询查询出所有的书,然后在遍历的时候再执行N个查询查询出作者信息,显然这样做是非常低效的,幸好我们还有预加载功能,可以将这N+1个查询减少到2个查询,在查询的时候,可以使用with方法指定哪个关系需要预加载。

1

2

3

4

$books = App\Book::with(&#39;author&#39;)->get();

foreach ($books as $book) {

    echo $book->author->name;

}

Copy after login

对于该操作,会执行下列两个sql

1

2

select * from books

select * from authors where id in (1, 2, 3, 4, 5, ...)

Copy after login

预加载多个关系

1

$books = App\Book::with(&#39;author&#39;, &#39;publisher&#39;)->get();

Copy after login

嵌套的预加载

1

$books = App\Book::with(&#39;author.contacts&#39;)->get();

Copy after login

带约束的预加载

1

2

3

4

5

$users = App\User::with([&#39;posts&#39; => function ($query) {

    $query->where(&#39;title&#39;, &#39;like&#39;, &#39;%first%&#39;);

}])->get();$users = App\User::with([&#39;posts&#39; => function ($query) {

    $query->orderBy(&#39;created_at&#39;, &#39;desc&#39;);

}])->get();

Copy after login

延迟预加载#

有时候,在上级模型已经检索出来之后,可能会需要预加载关联数据,可以使用load方法

1

2

3

4

$books = App\Book::all();if ($someCondition) {    $books->load(&#39;author&#39;, &#39;publisher&#39;);

}$books->load([&#39;author&#39; => function ($query) {

    $query->orderBy(&#39;published_date&#39;, &#39;asc&#39;);

}]);

Copy after login

关联模型插入

save方法

保存单个关联模型

1

2

$comment = new App\Comment([&#39;message&#39; => &#39;A new comment.&#39;]);

$post = App\Post::find(1);$post->comments()->save($comment);

Copy after login

保存多个关联模型

1

2

3

4

5

$post = App\Post::find(1);

$post->comments()->saveMany([   

new App\Comment([&#39;message&#39; => &#39;A new comment.&#39;]),   

new App\Comment([&#39;message&#39; => &#39;Another comment.&#39;]),

]);

Copy after login

save方法和多对多关联

多对多关联可以为save的第二个参数指定关联表中的属性

1

App\User::find(1)->roles()->save($role, [&#39;expires&#39; => $expires]);

Copy after login

上述代码会更新中间表的expires字段。

create方法

使用create方法与save方法的不同在于它是使用数组的形式创建关联模型的

1

2

$post = App\Post::find(1);$comment = $post->comments()->create([

    &#39;message&#39; => &#39;A new comment.&#39;,]);

Copy after login

更新 “Belongs To” 关系

更新belongsTo关系的时候,可以使用associate方法,该方法会设置子模型的外键

1

2

3

$account = App\Account::find(10);

$user->account()->associate($account);

$user->save();

Copy after login

要移除belongsTo关系的话,使用dissociate方法

1

$user->account()->dissociate();$user->save();

Copy after login

Many to Many 关系

中间表查询条件#

当查询时需要对使用中间表作为查询条件时,可以使用wherePivotwherePivotInorWherePivotorWherePivotIn添加查询条件。

1

2

3

$enterprise->with([&#39;favorites&#39; => function($query) {   

$query->wherePivot(&#39;enterprise_id&#39;, &#39;=&#39;, 12)->select(&#39;id&#39;);

}]);

Copy after login

Attaching / Detaching#

1

2

3

4

5

6

7

8

9

$user = App\User::find(1);

// 为用户添加角色

$user->roles()->attach($roleId);

// 为用户添加角色,更新中间表的expires字段

$user->roles()->attach($roleId, [&#39;expires&#39; => $expires]);

// 移除用户的单个角色

$user->roles()->detach($roleId);

// 移除用户的所有角色

$user->roles()->detach();

Copy after login

attach和detach方法支持数组参数,同时添加和移除多个

1

2

3

$user = App\User::find(1);

$user->roles()->detach([1, 2, 3]);

$user->roles()->attach([1 => [&#39;expires&#39; => $expires], 2, 3]);

Copy after login

更新中间表(关联表)字段

使用updateExistingPivot方法更新中间表

1

$user = App\User::find(1);$user->roles()->updateExistingPivot($roleId, $attributes);

Copy after login

同步中间表(同步关联关系)#

使用sync方法,可以指定两个模型之间只存在指定的关联关系

1

2

$user->roles()->sync([1, 2, 3]);

$user->roles()->sync([1 => [&#39;expires&#39; => true], 2, 3]);

Copy after login

上述两个方法都会让用户只存在1,2,3三个角色,如果用户之前存在其他角色,则会被删除。

更新父模型的时间戳#

假设场景如下,我们为一个帖子增加了一个新的评论,我们希望这个时候帖子的更新时间会相应的改变,这种行为在Eloquent中是非常容易实现的。

在子模型中使用$touches属性实现该功能

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

<?php

 

namespace App;

 

use Illuminate\Database\Eloquent\Model;class Comment extends Model{    /**

     * All of the relationships to be touched.

     *

     * @var array

     */

    protected $touches = [&#39;post&#39;];    /**

     * Get the post that the comment belongs to.

     */

    public function post()

    {        return $this->belongsTo(&#39;App\Post&#39;);

    }

}

Copy after login

现在,更新评论的时候,帖子的updated_at字段也会被更新

1

$comment = App\Comment::find(1);$comment->text = &#39;Edit to this comment!&#39;;$comment->save();

Copy after login

The above is the detailed content of Laravel framework - Detailed introduction to the advanced parts of EloquentORM. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

Hot Topics

Java Tutorial
1657
14
PHP Tutorial
1257
29
C# Tutorial
1230
24
Laravel Eloquent ORM in Bangla partial model search) Laravel Eloquent ORM in Bangla partial model search) Apr 08, 2025 pm 02:06 PM

LaravelEloquent Model Retrieval: Easily obtaining database data EloquentORM provides a concise and easy-to-understand way to operate the database. This article will introduce various Eloquent model search techniques in detail to help you obtain data from the database efficiently. 1. Get all records. Use the all() method to get all records in the database table: useApp\Models\Post;$posts=Post::all(); This will return a collection. You can access data using foreach loop or other collection methods: foreach($postsas$post){echo$post->

Laravel Introduction Example Laravel Introduction Example Apr 18, 2025 pm 12:45 PM

Laravel is a PHP framework for easy building of web applications. It provides a range of powerful features including: Installation: Install the Laravel CLI globally with Composer and create applications in the project directory. Routing: Define the relationship between the URL and the handler in routes/web.php. View: Create a view in resources/views to render the application's interface. Database Integration: Provides out-of-the-box integration with databases such as MySQL and uses migration to create and modify tables. Model and Controller: The model represents the database entity and the controller processes HTTP requests.

Solve caching issues in Craft CMS: Using wiejeben/craft-laravel-mix plug-in Solve caching issues in Craft CMS: Using wiejeben/craft-laravel-mix plug-in Apr 18, 2025 am 09:24 AM

When developing websites using CraftCMS, you often encounter resource file caching problems, especially when you frequently update CSS and JavaScript files, old versions of files may still be cached by the browser, causing users to not see the latest changes in time. This problem not only affects the user experience, but also increases the difficulty of development and debugging. Recently, I encountered similar troubles in my project, and after some exploration, I found the plugin wiejeben/craft-laravel-mix, which perfectly solved my caching problem.

Laravel user login function Laravel user login function Apr 18, 2025 pm 12:48 PM

Laravel provides a comprehensive Auth framework for implementing user login functions, including: Defining user models (Eloquent model), creating login forms (Blade template engine), writing login controllers (inheriting Auth\LoginController), verifying login requests (Auth::attempt) Redirecting after login is successful (redirect) considering security factors: hash passwords, anti-CSRF protection, rate limiting and security headers. In addition, the Auth framework also provides functions such as resetting passwords, registering and verifying emails. For details, please refer to the Laravel documentation: https://laravel.com/doc

Laravel framework installation method Laravel framework installation method Apr 18, 2025 pm 12:54 PM

Article summary: This article provides detailed step-by-step instructions to guide readers on how to easily install the Laravel framework. Laravel is a powerful PHP framework that speeds up the development process of web applications. This tutorial covers the installation process from system requirements to configuring databases and setting up routing. By following these steps, readers can quickly and efficiently lay a solid foundation for their Laravel project.

Laravel's geospatial: Optimization of interactive maps and large amounts of data Laravel's geospatial: Optimization of interactive maps and large amounts of data Apr 08, 2025 pm 12:24 PM

Efficiently process 7 million records and create interactive maps with geospatial technology. This article explores how to efficiently process over 7 million records using Laravel and MySQL and convert them into interactive map visualizations. Initial challenge project requirements: Extract valuable insights using 7 million records in MySQL database. Many people first consider programming languages, but ignore the database itself: Can it meet the needs? Is data migration or structural adjustment required? Can MySQL withstand such a large data load? Preliminary analysis: Key filters and properties need to be identified. After analysis, it was found that only a few attributes were related to the solution. We verified the feasibility of the filter and set some restrictions to optimize the search. Map search based on city

Laravel and the Backend: Powering Web Application Logic Laravel and the Backend: Powering Web Application Logic Apr 11, 2025 am 11:29 AM

How does Laravel play a role in backend logic? It simplifies and enhances backend development through routing systems, EloquentORM, authentication and authorization, event and listeners, and performance optimization. 1. The routing system allows the definition of URL structure and request processing logic. 2.EloquentORM simplifies database interaction. 3. The authentication and authorization system is convenient for user management. 4. The event and listener implement loosely coupled code structure. 5. Performance optimization improves application efficiency through caching and queueing.

How to learn Laravel How to learn Laravel for free How to learn Laravel How to learn Laravel for free Apr 18, 2025 pm 12:51 PM

Want to learn the Laravel framework, but suffer from no resources or economic pressure? This article provides you with free learning of Laravel, teaching you how to use resources such as online platforms, documents and community forums to lay a solid foundation for your PHP development journey from getting started to master.

See all articles