博客 / 詳情

返回

最為常用的Laravel操作(1)-Eloquent模型

快速入門

更換表名

protected $table = 'my_flights';

更換主鍵名稱

protected $primaryKey  = 'id';

注意: Eloquent 默認主鍵字段是自增的整型數據, 這意味着主鍵將會被自動轉化為 int 類型, 如果你想要使用非自增或非數字類型主鍵, 必須在對應模型中設置 $incrementing 屬性為 false , 如果主鍵不是整型, 還要設置 $keyType 屬性值為 string.

關閉時間戳記錄

public $timestamps = false;

獲取模型數據

// Eloquent 的 all 方法返回模型表的所有結果
$flights = App\Flight::all();

foreach ($flights as $flight) {
    echo $flight->name;
}

// 添加約束條件
$flights = App\Flight::where('active', 1)
    ->orderBy('name', 'desc')
    ->take(10)
    ->get();

獲取單個模型

// 通過主鍵獲取模型
$flight = App\Flight::find(1);
// 獲取匹配查詢條件的第一個模型
$flight = App\Flight::where('active', 1)->first();
// 通過傳遞主鍵數組來調用 find 方法, 這將會返回匹配記錄集合
$flights = App\Flight::find([1, 2, 3]);

獲取聚合結果

$count = App\Flight::where('active', 1)->count();
$max = App\Flight::where('active', 1)->max('price');

插入記錄

$flight = new Flight;
$flight->name = $request->name;
$flight->save();

更新模型

$flight = App\Flight::find(1);
$flight->name = 'New Flight Name';
$flight->save();

批量更新

App\Flight::where('active', 1)
    ->where('destination', 'San Diego')
    ->update(['delayed' => 1]);

刪除模型

// 刪除
$flight = App\Flight::find(1);
$flight->delete();

// 通過主鍵刪除模型
App\Flight::destroy(1);
App\Flight::destroy([1, 2, 3]);
App\Flight::destroy(1, 2, 3);

// 通過查詢刪除模型
$deletedRows = App\Flight::where('active', 0)->delete();

軟刪除

// Eloquent 模型
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Flight extends Model
{
    use SoftDeletes;
    /**
     * 應該被調整為日期的屬性
     *
     * @var array
     */
    protected $dates = ['deleted_at'];
}

// 數據表結構添加 deleted_at 列
Schema::table('flights', function ($table) {
    $table->softDeletes();
});

// 判斷給定模型實例是否被軟刪除, 可以使用 trashed 方法
if ($flight->trashed()) {
    // ...
}

// 查詢被軟刪除的模型
$flights = App\Flight::withTrashed()
    ->where('account_id', 1)
    ->get();
$flight->history()->withTrashed()->get();

// 只獲取軟刪除模型
$flights = App\Flight::onlyTrashed()
    ->where('airline_id', 1)
    ->get();

// 恢復軟刪除模型
$flight->restore();

// 使用 restore 方法來快速恢復多個模型, 不會觸發任何模型事件
App\Flight::withTrashed()
    ->where('airline_id', 1)
    ->restore();
$flight->history()->restore();

本地作用域

/**
 * 只包含活躍用户的查詢作用域
 *
 * @return \Illuminate\Database\Eloquent\Builder
 */
public function scopePopular($query)
{
    return $query->where('votes', '>', 100);
}

/**
 * 只包含激活用户的查詢作用域
 *
 * @return \Illuminate\Database\Eloquent\Builder
 */
public function scopeActive($query)
{
    return $query->where('active', 1);
}
// 使用本地作用域
$users = App\User::popular()->active()->orderBy('created_at')->get();

動態作用域

/**
 * 讓查詢只包含給定類型的用户
 *
 * @param \Illuminate\Database\Eloquent\Builder $query
 * @param mixed $type
 * @return \Illuminate\Database\Eloquent\Builder
 */
public function scopeOfType($query, $type)
{
    return $query->where('type', $type);
}
// 使用動態作用域
$users = App\User::ofType('admin')->get();

模型關聯

一對一關聯

// 擁有
class User extends Model
{
    /**
     * 獲取關聯到用户的手機
     */
    public function phone()
    {
        // Phone : 關聯的模型
        // Phone : user_id 外鍵
        // User  : id      主鍵
        return $this->hasOne('App\Phone', 'user_id', 'id');
    }
}

// 所屬
class Phone extends Model
{
    /**
     * 獲取擁有該手機的用户
     */
    public function user()
    {
        // User  : 所屬的模型
        // Phone : user_id 外鍵
        // User  : id      父模型主鍵
        return $this->belongsTo('App\User', 'user_id', 'id');
    }
}

// 空模型
class Article extends Model
{
    /**
     * 獲取文章作者
     */
    public function user()
    {
        return $this->belongsTo('App\User')->withDefault(function ($user) {
            $user->name = 'Guest Author';
        });
    }
}

一對多關聯

// 擁有
class Post extends Model
{
    /**
     * 獲取博客文章的評論
     */
    public function comments()
    {
        // Comment : 關聯的模型
        // Comment : post_id 外鍵
        // Post    : id      主鍵
        return $this->hasMany('App\Comment', 'post_id', 'id');
    }
}

// 所屬
class Comment extends Model
{
    /**
     * 獲取評論對應的博客文章
     */
    public function post()
    {
        // Post    : 關聯的模型
        // Comment : post_id 外鍵
        // Post    : id      父模型主鍵
        return $this->belongsTo('App\Post', 'post_id', 'id');
    }
}

多對多關聯

// 關聯
class User extends Model
{
    /**
     * 用户角色
     */
    public function roles()
    {
        // Role       : 關聯的模型
        // user_roles : 中間表名稱
        // user_id    : 對應到模型主鍵
        // role_id    : 對應到關聯主鍵
        return $this->belongsToMany('App\Role', 'user_roles', 'user_id', 'role_id');
    }
}

// 獲取中間表字段, 通過 pivot 屬性
$user = App\User::find(1);
foreach ($user->roles as $role) {
    echo $role->pivot->created_at;
}

// 當 pivot 表包含額外的屬性時, 必須定義關聯時先指定
return $this->belongsToMany('App\Role')->withPivot('column1', 'column2');

// 自動包含created_at 和 updated_at
return $this->belongsToMany('App\Role')->withTimestamps();

// 更換 pivot 為 subscription, 提升可讀性
return $this->belongsToMany('App\Podcast')
            ->as('subscription')
            ->withTimestamps();
$users = User::with('podcasts')->get();
foreach ($users->flatMap->podcasts as $podcast) {
    echo $podcast->subscription->created_at;
}

渴求式加載

// select * from books
$books = App\Book::all();
// select * from authors where id in (1, 2, 3, 4, 5, ...)
$books = App\Book::with('author')->get();
foreach ($books as $book) {
    echo $book->author->name;
}

// 渴求式加載多個關聯關係
$books = App\Book::with('author', 'publisher')->get();

// 嵌套的渴求式加載
$books = App\Book::with('author.contacts')->get();

// 渴求式加載指定字段
// 注: 使用這個特性時, id 字段是必須列出的
$users = App\Book::with('author:id,name')->get(); 

// 帶條件約束的渴求式加載
$users = App\User::with(['posts' => function ($query) {
    $query->where('title', 'like', '%first%');
}])->get();

插入 / 更新關聯模型

// 插入關聯模型
$comment = new App\Comment(['message' => 'A new comment.']);
$post = App\Post::find(1);
// 調用 comments 方法獲取關聯關係實例, save 將添加 post_id 到 Comment 模型中
$post->comments()->save($comment);

// 保存多個關聯模型
$post = App\Post::find(1);
$post->comments()->saveMany([
    new App\Comment(['message' => 'A new comment.']),
    new App\Comment(['message' => 'Another comment.']),
]);

// 使用 create 創建, 與 save 不同的是, 它j接收一個關聯數組, create 方法遵循模型屬性的批量賦值操作
$post = App\Post::find(1);
$comment = $post->comments()->create([
    'message' => 'A new comment.',
]);

// 保存多個關聯模型
$post = App\Post::find(1);
$post->comments()->createMany([
    [
        'message' => 'A new comment.',
    ],
    [
        'message' => 'Another new comment.',
    ],
]);

// 更新從屬關聯關係 (belongsTo)
$account = App\Account::find(10);
// associate 方法會在子模型設置外鍵
$user->account()->associate($account);
$user->save();

// 移除關聯 (belongsTo) 
// dissociate 方法會設置關聯關係的外鍵為 null
$user->account()->dissociate();
$user->save();

附加 / 分離多對多關聯模型

$user = App\User::find(1);
// 在連接模型的中間表中插入記錄
$user->roles()->attach($roleId);
// 插入數據和附加的數組到中間表
$user->roles()->attach($roleId, ['expires' => $expires]);

// 從中間表中移除相應的記錄: 指定用户移除某個角色
$user->roles()->detach($roleId);
// 從中間表中移除相應的記錄: 指定用户移除所有角色
$user->roles()->detach();

// attach 和 detach 還接收數組形式的 ID 作為輸入
$user = App\User::find(1);
$user->roles()->detach([1, 2, 3]);
$user->roles()->attach([
    1 => ['expires' => $expires],
    2 => ['expires' => $expires]
]);

在中間表上保存額外數據

處理多對多關聯時, save 方法接收中間表數組作為第二個參數:

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

訪問器和修改器

訪問器和修改器 允許你在獲取模型屬性或設置其值時格式化 Eloquent 屬性.

例如, 你可能想要使用 Laravel 加密器對存儲在數據庫中的數據進行加密, 並且在 Eloquent 模型中訪問時自動進行解密.

除了自定義訪問器和修改器, Eloquent 還可以自動轉換日期字段為 Carbon 實例甚至 將文本轉換為 JSON .

訪問器

class User extends Model
{
    /**
     * 獲取用户的名字
     *
     * @param  string  $value
     * @return string
     */
    public function getFirstNameAttribute($value)
    {
        return ucfirst($value);
    }

    /**
    * 獲取用户的全名
    *
    * @return string
    */
    public function getFullNameAttribute()
    {
        return "{$this->first_name} {$this->last_name}";
    }
}
// 訪問 first_name 屬性
$firstName = App\User::find(1)->first_name;

修改器

class User extends Model
{
    /**
     * 設置用户的名字
     *
     * @param  string  $value
     * @return string
     */
    public function setFirstNameAttribute($value)
    {
        $this->attributes['first_name'] = strtolower($value);
    }
}
// 設置 first_name 屬性
App\User::find(1)->first_name = 'Sally';

日期修改器

默認情況下, Eloquent 將會轉化 created_atupdated_at 列的值為 Carbon 實例, 該類繼承自 PHP 原生的 Datetime 類, 並提供了各種有用的方法. 你可以自定義哪些字段被自動調整修改, 甚至可以通過重寫模型中的 $dates 屬性完全禁止調整:

class User extends Model
{
    /**
     * 應該被調整為日期的屬性
     *
     * @var array
     */
    protected $dates = [
        'created_at', 
        'updated_at', 
        'disabled_at'
    ];
}

// 自動轉換並存儲到數據庫中
$user = App\User::find(1);
$user->disabled_at = Carbon::now();
$user->save();

// 使用 Carbon 提供的方法
$user = App\User::find(1);
return $user->disabled_at->getTimestamp();

模型日期格式

默認情況下, 時間戳的格式是 Y-m-d H:i:s , 可以結合 $dateFormat 屬性自定義格式:

class Flight extends Model
{
    /**
     * 模型日期的存儲格式
     *
     * @var string
     */
    protected $dateFormat = 'U';
}

屬性轉換

支持的轉換類型: integer , real , float , double , string , boolean , object , array , collection , date , datetimetimestamp .

如果數據庫有一個 JSONTEXT 字段類型包含了序列化 JSON, 可使用 array 轉換, 將自動進行 序列化反序列化 .

class User extends Model
{
    /**
     * 應該被轉化為原生類型的屬性
     *
     * @var array
     */
    protected $casts = [
        // 轉換 is_admin 屬性: 從 integer (0/1) 轉換為 boolean
        'is_admin' => 'boolean',
        // 訪問 options 屬性將會自動從 JSON 反序列化為 PHP 數組
        // 設置 options 屬性的值時, 給定數組將會自動轉化為 JSON 以供存儲
        'options' => 'array',
    ];
}

// is_admin 屬性已經被轉換了:
if ($user->is_admin) {
    //
}

// 自動序列化和反序列化
$user = App\User::find(1);
$options = $user->options;
$options['key'] = 'value';
$user->options = $options;
$user->save();


文章來源於本人博客,發佈於 2018-06-10,原文鏈接:https://imlht.com/archives/152/
user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.