public function products()
{
return $this->hasMany(Product::class);
}
public function productsByName()
{
return $this->hasMany(Product::class)->orderBy('name');
}
在 Eloquent 关系中添加条件
假如你经常在模型关联关系中添加某些相同的 where 条件,可以单独创建一个方法。
Model:
public function comments()
{
return $this->hasMany(Comment::class);
}
public function approved_comments()
{
return $this->hasMany(Comment::class)->where('approved', 1);
}
class ProductTag extends Model
{
protected $with = ['product'];
public function __construct() {
parent::__construct();
$this->with = ['product'];
if (auth()->check()) {
$this->with[] = 'user';
}
}
}
使用 hasMany 代替 belongsTo
在关联关系中,如果创建子关系的记录中需要用到父关系的 ID ,那么使用 hasMany 比使用 belongsTo 更简洁。
// if Post -> belongsTo(User), and User -> hasMany(Post)...
// Then instead of passing user_id...
Post::create([
'user_id' => auth()->id(),
'title' => request()->input('title'),
'post_text' => request()->input('post_text'),
]);
// Do this
auth()->user()->posts()->create([
'title' => request()->input('title'),
'post_text' => request()->input('post_text'),
]);
// Before Laravel 7
Schema::table('posts', function (Blueprint $table)) {
$table->unsignedBigInteger('user_id');
$table->foreign('user_id')->references('id')->on('users');
}
// From Laravel 7
Schema::table('posts', function (Blueprint $table)) {
$table->foreignId('user_id')->constrained();
}
// Or, if your field is different from the table reference
Schema::table('posts', function (Blueprint $table)) {
$table->foreignId('created_by_id')->constrained('users', 'column');
}
// in app/Models/User.php
public function roles()
{
return $this->belongsToMany(Role::class)
->using(RoleUser::class)
->withPivot(['team_id']);
}
// app/Models/RoleUser.php: notice extends Pivot, not Model
use Illuminate\Database\Eloquent\Relations\Pivot;
class RoleUser extends Pivot
{
public function team()
{
return $this->belongsTo(Team::class);
}
}
// Then, in Controller, you can do:
$firstTeam = auth()->user()->roles()->first()->pivot->team->name;
// if your Book hasMany Reviews...
$book = App\Book::first();
$book->loadCount('reviews');
// Then you get access to $book->reviews_count;
// Or even with extra condition
$book->loadCount(['reviews' => function ($query) {
$query->where('rating', 5);
}]);
// If you have a quiz and want to randomize questions...
// 1. If you want to get questions in random order:
$questions = Question::inRandomOrder()->get();
// 2. If you want to also get question options in random order:
$questions = Question::with(['answers' => function($q) {
$q->inRandomOrder();
}])->inRandomOrder()->get();
class Tournament extends Model
{
public function countries()
{
return $this->belongsToMany(Country::class)->withPivot(['position']);
}
}
class TournamentsController extends Controller
public function whatever_method() {
$tournaments = Tournament::with(['countries' => function($query) {
$query->orderBy('position');
}])->latest()->get();
}
whereHas 的一个更简短的方法
在 Laravel 8.57 中发布:通过包含一个简单条件的简短方法来写 whereHas()。
// Before
User::whereHas('posts', function ($query) {
$query->where('published_at', '>', now());
})->get();
// After
User::whereRelation('posts', 'published_at', '>', now())->get();
你可以为你的模型关联添加条件
class User
{
public function posts()
{
return $this->hasMany(Post::class);
}
// with a getter
public function getPublishedPostsAttribute()
{
return $this->posts->filter(fn ($post) => $post->published);
}
// with a relationship
public function publishedPosts()
{
return $this->hasMany(Post::class)->where('published', true);
}
}
// BEFORE: the foreign key is taken from the Post model
$post->author_id === $user->id;
// BEFORE: An additional request is made to get the User model from the Author relationship
$post->author->is($user);
// AFTER
$post->author()->is($user);
// User Model
class User extends Model
{
protected $connection = 'conn_1';
public function posts()
{
return $this->hasMany(Post::class);
}
}
// Post Model
class Post extends Model
{
protected $connection = 'conn_2';
public function user()
{
return $this->belongsTo(User::class, 'user_id');
}
}
// wherehas()
$posts = Post::whereHas('user', function ($query) use ($request) {
$query->from('db_name_conn_1.users')->where(...);
})->get();
// Migrations
Schema::create('role_user', function ($table) {
$table->unsignedId('user_id');
$table->unsignedId('role_id');
$table->timestamp('assigned_at');
})
// first param for the record id
// second param for the pivot records
$user->roles()->updateExistingPivot(
$id, ['assigned_at' => now()],
);
public function historyItems(): HasMany
{
return $this
->hasMany(ApplicationHealthCheckHistoryItem::class)
->orderByDesc('created_at');
}
public function latestHistoryItem(): HasOne
{
return $this
->hasOne(ApplicationHealthCheckHistoryItem::class)
->latestOfMany();
}
用 ofMany 代替你的自定义查询
class User extends Authenticable {
// Get most popular post of user
public function mostPopularPost() {
return $this->hasOne(Post::class)->ofMany('like_count', 'max');
}
}