close

Relations on databases, 

$user->posts()->where('active', 1)->get();

  如果我們想要使用這種方式去關聯其他table的話

需要再User Class使用方法

class User extends Model
{
    /**
     * Get the phone record associated with the user.
     */
    public function phone()
    {
        return $this->hasOne('App\Phone');
    }
}

  這樣Eloquent Dynamic binding自動會幫我們抓取資料,上述範例就可以讓我們使用$user->phone(); 取得phone.

一個user 僅有一個phone,預備機制,phone tables內要有user_id,(FK)這樣就會自動綁定,

return $this->hasOne('App\Phone', 'foreign_key');

另外加參數可以附加FK,這樣的機制下,我們會拿user_id去phone裡面找user_id是否吻合,並取出資料。

 

class Phone extends Model
{
    /**
     * Get the user that owns the phone.
     */
    public function user()
    {
        return $this->belongsTo('App\User');
    }
}

  反向關系 Inverse relations, 在Phone裡面使用belongsTo(),變相表示phone屬於user. 上述例子eloquent會取抓phone裡面的user_id去跟User table的id比對

預設上Eloquent會抓取method name加上_id 當成FK,上面看到method 是 user()  所以user + _id  這樣就會是拿Phone裡面的user_id,假設今天你的Phone FK不叫作

user_id,名字是userforeignkey_id,那上面的範例就要從user()改成userforeignkey(),或者是你直接在方法內給第二個參數名稱,就會使用該參數當作FK了ˊ!! 

$this->belongsTo('App\User', 'foreign_key');

假設你的user model不是使用id當作FK,那你就必須使用第三個參數,來代表你user table的Primary Key了!

public function user()
{
    return $this->belongsTo('App\User', 'foreign_key', 'other_key');
}

One To Many

 

class Post extends Model
{
    /**
     * Get the comments for the blog post.
     */
    public function comments()
    {
        return $this->hasMany('App\Comment');
    }
}

A Post  can have infinite number of comments. use hasMany.

一樣eloquent預設會使用model name 加上 _id,所以會去Post找post_id (預設的情況下)

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

  定義完就可以使用這個方法拉! A collection

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

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

  使用foreach去尋訪

$comment = App\Post::find(1)->comments()->where('title', 'foo')->first();

  you can retrieved comments and use builder to chain methods.

使用builder pattern去chainning.

return $this->hasMany('App\Comment', 'foreign_key');

return $this->hasMany('App\Comment', 'foreign_key', 'local_key');

  一樣可以去override foreign key(in comment table)和 local key (post table)

Inverse()

class Comment extends Model
{
    /**
     * Get the post that owns the comment.
     */
    public function post()
    {
        return $this->belongsTo('App\Post');
    }
}

  從comment回抓post  

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

echo $comment->post->title;

$comment->post->attributes or $comment->posts()->attibutes;

 

 

般來說會使用model name+上_id去尋找child table的foreign key

但是在inverse relation 則是使用method name + _id去尋找該Model中的 foreign key

 

Many To Many

Many to many 通常會使用到三個表,代表有個單純 join 用的table, =>  intermediate table

範例是Users、Roles、role_user,而role_user上有user_id、role_id

class User extends Model
{
    /**
     * The roles that belong to the user.
     */
    public function roles()
    {
        return $this->belongsToMany('App\Role');
    }
}

  inverse relation ,user belongsToMany()  Role,User可以扮演多個腳色

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

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

  使用$user->roles  or $user->roles(); 去作巡迴的查找

同樣的你可以透過builder pattern繼續Channing

$roles = App\User::find(1)->roles()->orderBy('name')->get();

  當使用上述方法時,Eloquent是怎麼跑的呢?  Eloqunet會透過joinning table將兩個table join起來,並且會照著 alphabetical order

當然你可以串改第二個參數,來指定要使用的join table,如下

return $this->belongsToMany('App\Role', 'role_user');

  另外你也可以明確指示在joinning table所使用的key

return $this->belongsToMany('App\Role', 'role_user', 'user_id', 'role_id');

  user_id是指當前的Model指向另一個Model的FK,以上述例子代表我們是在Role裡面使用這行, 我們拿 User table內的user_id當foreign key 比對role_user,第四個argument Role table則是使用role_id,

 

pivot table,樞紐分析表,在多對多的特殊關係下的應用,

return $this->belongsToMany('App\Role')->withPivot('column1', 'column2');
return $this->belongsToMany('App\Podcast')
                ->as('subscription')
                ->withTimestamps();

​​​​​​​

$users = User::with('podcasts')->get();

foreach ($users->flatMap->podcasts as $podcast) {
    echo $podcast->subscription->created_at;
}

  當有pivot這個功能時,你可以使用with('podcast'),代表某個使用者訂閱了那些podcasts.

 

上面pivot不太詳細,請看下面的案例

今天有country、post、user的model,而country是user的一部分,你可以透過關聯找到某個國家的所有posts.

countries
    id - integer
    name - string

users
    id - integer
    country_id - integer
    name - string

posts
    id - integer
    user_id - integer
    title - string

​​​​​​​

Though posts does not contain a country_id column, the hasManyThrough relation provides access to a country's posts via $country->posts. To perform this query, Eloquent inspects the country_id on the intermediate users table. After finding the matching user IDs, they are used to query the posts table. ​​​​​​​

 

這樣就可以直接使用$country->posts 間接存取country的posts.

但是你必須在country model define.

class Country extends Model
{
    /**
     * Get all of the posts for the country.
     */
    public function posts()
    {
        return $this->hasManyThrough('App\Post', 'App\User');
    }
}

Country透過User 可以拿到很多Post. First argument  is the name of the final model we wish to access ​​​​​​​

while the second argument is the name of the intermediate model. ​​​​​​​

 

未完待續....

arrow
arrow
    文章標籤
    Eloquent Databases laravel
    全站熱搜

    蕭瑞文 發表在 痞客邦 留言(0) 人氣()