Laravel Model

该文介绍了 Laravel 的 Eloquent 模型的常见用法。

模型约定

默认情况下Model会自动关联一个复数形式的数据表,也可以指定一个自定义的数据表名称:

protected $table = 'my_tables';

Eloquent 也会假设每个数据表都有一个叫做 id 的主键字段。如果主键不是ID,也可以定义一个 $primaryKey 属性来重写这个约定。

protected $primaryKey = 'my_id';

默认情况下,Eloquent 会预计你的数据表中有 created_at 和 updated_at 字段。如果你不希望让 Eloquent 来自动维护这两个字段,可在模型内将 $timestamps 属性设置为 false

public $timestamps = false;

默认情况下,所有的 Eloquent 模型会使用应用程序中默认的数据库连接设置。如果你想为模型指定不同的连接,可以使用 $connection 属性:

protected $connection = 'mssql';

可以被批量赋值的属性

protected $fillable = ['name'];

其他定义:

protected $dateFormat = 'U';//模型日期列的存储格式
const CREATED_AT = 'creation_date'; //定义时间戳的字段名称
const UPDATED_AT = 'last_update'; //定义时间戳的字段名称
protected $guarded = ['price'];//不能被批量赋值的属性
protected $dates = ['deleted_at'];//应该被调整为日期的属性

模型查询

// 查询全部数据
$flights = App\Flight::all();

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

// 通过主键取回一个模型 Model::find(1); // 使用主键数组作为参数 Model::find([1, 2, 3]); // 使用双主键进行查找 Model::find(array('first', 'last')); // 查找失败时抛出异常 Model::findOrFail(1); // 使用双主键进行查找, 失败时抛出异常 Model::findOrFail(array('first', 'last')); // 取回符合查询限制的所有 Model::where('foo', '=', 'bar')->get(); // 取回符合查询限制的第一个模型 Model::where('foo', '=', 'bar')->first(); // 是否存在 Model::where('foo', '=', 'bar')->exists(); // 动态属性查找 Model::whereFoo('bar')->first(); // 查找失败时抛出异常 Model::where('foo', '=', 'bar')->firstOrFail(); Model::where('foo', '=', 'bar')->count(); // 比如 count, max,min, avg,还有 sum Model::where('active', 1)->max('price'); // 输出原始的查询语句 Model::where('foo', '=', 'bar')->toSql(); Model::whereRaw('foo = bar and cars = 2', array(20))->get(); Model::on('connection-name')->find(1); Model::with('relation')->get(); Model::all()->take(10); Model::all()->skip(10); // 默认的 Eloquent 排序是上升排序 Model::orderBy('column', 'asc')->get(); Model::orderBy('column', 'desc')->get(); // 在查询结果中包括带被软删除的模型 Model::withTrashed()->where('cars', 2)->get(); // 查找只带有软删除的模型 Model::onlyTrashed()->where('cars', 2)->get();

插入 & 更新模型

创建新数据

Model::create(array('key' => 'value'));

$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]);

// 通过属性找到第一条相匹配的数据或创造一条新数据 Model::firstOrCreate(array('key' => 'value')); // 程序会查询 name 为 antto 的数据是否存在,如果不存在,才将 name, avatar, gender 数据一并创建新数据 $user = User::firstOrCreate( ['name' => 'antto'], [ 'avatar' => 'http://....', 'gender' => 'male', ] ]); // 通过属性找到第一条相匹配的数据或实例化一条新数据 Model::firstOrNew(array('key' => 'value')); // 通过属性找到相匹配的数据并更新,如果不存在即创建 Model::updateOrCreate(array('search_key' => 'search_value'), array('key' => 'value')); // 使用属性的数组来填充一个模型, 用的时候要小心「Mass Assignment」安全问题 ! Model::fill($attributes);

删除

启动模型上的软删除

use Illuminate\Database\Eloquent\SoftDeletes;
class Flight extends Model
{
    use SoftDeletes;
}

Model::destroy(1); // 多主键删除 Model::destroy([1, 2, 3]); Model::where('foo', '=', 'bar')->delete(); // 恢复被软删除的模型 Model::withTrashed()->where('cars', 2)->restore(); Model::where('cars', 2)->forceDelete();

作用域

定义

public function scopePopular($query)
{
    return $query->where('votes', '>', 100);
}

public function scopeActive($query)
{
    return $query->where('active', 1);
}

使用

$users = App\User::popular()->active()->orderBy('created_at')->get();

模型关联

// 一对一 - User::phone()
 return $this->hasOne('App\Phone', 'foreign_key', 'local_key');
// 一对一 - Phone::user(), 定义相对的关联
 return $this->belongsTo('App\User', 'foreign_key', 'other_key');

// 一对多 - Post::comments()
 return $this->hasMany('App\Comment', 'foreign_key', 'local_key');
//  一对多 - Comment::post()
 return $this->belongsTo('App\Post', 'foreign_key', 'other_key');

// 多对多 - User::roles();
 return $this->belongsToMany('App\Role', 'user_roles', 'user_id', 'role_id');
// 多对多 - Role::users();
 return $this->belongsToMany('App\User');
// 多对多 - Retrieving Intermediate Table Columns
$role->pivot->created_at;
// 多对多 - 中介表字段
 return $this->belongsToMany('App\Role')->withPivot('column1', 'column2');
// 多对多 - 自动维护 created_at 和 updated_at 时间戳
 return $this->belongsToMany('App\Role')->withTimestamps();

// 远层一对多 - Country::posts(), 一个 Country 模型可能通过中介的 Users
 // 模型关联到多个 Posts 模型(User::country_id)
 return $this->hasManyThrough('App\Post', 'App\User', 'country_id', 'user_id');

// 多态关联 - Photo::imageable()
 return $this->morphTo();
// 多态关联 - Staff::photos()
 return $this->morphMany('App\Photo', 'imageable');
// 多态关联 - Product::photos()
 return $this->morphMany('App\Photo', 'imageable');
// 多态关联 - 在 AppServiceProvider 中注册你的「多态对照表」
 Relation::morphMap([
    'Post' => App\Post::class,
    'Comment' => App\Comment::class,
]);

// 多态多对多关联 - 涉及数据库表: posts,videos,tags,taggables
 // Post::tags()
 return $this->morphToMany('App\Tag', 'taggable');
// Video::tags()
 return $this->morphToMany('App\Tag', 'taggable');
// Tag::posts()
 return $this->morphedByMany('App\Post', 'taggable');
// Tag::videos()
 return $this->morphedByMany('App\Video', 'taggable');

// 查找关联
$user->posts()->where('active', 1)->get();
// 获取所有至少有一篇评论的文章...
$posts = App\Post::has('comments')->get();
// 获取所有至少有三篇评论的文章...
$posts = Post::has('comments', '>=', 3)->get();
// 获取所有至少有一篇评论被评分的文章...
$posts = Post::has('comments.votes')->get();
// 获取所有至少有一篇评论相似于 foo% 的文章
$posts = Post::whereHas('comments', function ($query) {
    $query->where('content', 'like', 'foo%');
})->get();

// 预加载
$books = App\Book::with('author')->get();
$books = App\Book::with('author', 'publisher')->get();
$books = App\Book::with('author.contacts')->get();

// 延迟预加载
$books->load('author', 'publisher');

// 写入关联模型
$comment = new App\Comment(['message' => 'A new comment.']);
$post->comments()->save($comment);
// Save 与多对多关联
$post->comments()->saveMany([
    new App\Comment(['message' => 'A new comment.']),
    new App\Comment(['message' => 'Another comment.']),
]);
$post->comments()->create(['message' => 'A new comment.']);

// 更新「从属」关联
$user->account()->associate($account);
$user->save();
$user->account()->dissociate();
$user->save();

// 附加多对多关系
$user->roles()->attach($roleId);
$user->roles()->attach($roleId, ['expires' => $expires]);
// 从用户上移除单一身份...
$user->roles()->detach($roleId);
// 从用户上移除所有身份...
$user->roles()->detach();
$user->roles()->detach([1, 2, 3]);
$user->roles()->attach([1 => ['expires' => $expires], 2, 3]);

// 任何不在给定数组中的 IDs 将会从中介表中被删除。
$user->roles()->sync([1, 2, 3]);
// 你也可以传递中介表上该 IDs 额外的值:
$user->roles()->sync([1 => ['expires' => true], 2, 3]);

384 total views, 2 views today

Revisions

No comments yet.

发表评论