Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Document withAttributes #10148

Open
wants to merge 1 commit into
base: 11.x
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions eloquent-relationships.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
- [Has One of Many](#has-one-of-many)
- [Has One Through](#has-one-through)
- [Has Many Through](#has-many-through)
- [Scoped Relationships](#scoped-relationships)
- [Many to Many Relationships](#many-to-many)
- [Retrieving Intermediate Table Columns](#retrieving-intermediate-table-columns)
- [Filtering Queries via Intermediate Table Columns](#filtering-queries-via-intermediate-table-columns)
Expand Down Expand Up @@ -612,6 +613,50 @@ return $this->through('environments')->has('deployments');
return $this->throughEnvironments()->hasDeployments();
```

<a name="scoped-relationships"></a>
### Scoped relationships

Of course, you may add constraints and other query methods in your relationship definitions if you need a more specific query every time. And existing scopes can be used to define other, more narrowly scoped relationships.

class User extends Model
{
public function posts(): HasMany
{
return $this->hasMany(Post::class)->latest();
}

public function highlights(): HasMany
{
return $this->posts()->where('featured', true)->take(3);
}
}

You can also use [query scopes](/docs/{{version}}/eloquent#query-scopes) and [pending attributes](/docs/{{version}}/eloquent#pending-attributes) in your relationship definitions.

class User extends Model
{
public function posts(): HasMany
{
return $this->hasMany(Post::class);
}

/**
* The posts that are only visible to owner.
*/
public function drafts(): HasMany
{
return $this->posts()->withAttributes('hidden', true);
}
}

The use of `withAttributes` allows you to both query and create models with the specified constraints applied:

// Retrieve user's hidden posts
$user->drafts;

// Create a new hidden post belonging to $user
$user->drafts()->create(['title' => 'WIP...']);

<a name="many-to-many"></a>
## Many to Many Relationships

Expand Down Expand Up @@ -781,6 +826,11 @@ You can also filter the results returned by `belongsToMany` relationship queries
->as('subscriptions')
->wherePivotNotNull('expired_at');

Note that `wherePivot` adds a constraint for querying but does not add the specified value when creating new models via the defined relationship. If you need to both query and create relationships with a "scoped" pivot, you may use the `withPivotValue` method:

return $this->belongsToMany(Role::class)
->withPivotValue('approved', 1);

<a name="ordering-queries-via-intermediate-table-columns"></a>
### Ordering Queries via Intermediate Table Columns

Expand Down
33 changes: 33 additions & 0 deletions eloquent.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
- [Query Scopes](#query-scopes)
- [Global Scopes](#global-scopes)
- [Local Scopes](#local-scopes)
- [Pending Attributes](#pending-attributes)
- [Comparing Models](#comparing-models)
- [Events](#events)
- [Using Closures](#events-using-closures)
Expand Down Expand Up @@ -1390,6 +1391,38 @@ Once the expected arguments have been added to your scope method's signature, yo

$users = User::ofType('admin')->get();

<a name="pending-attributes"></a>
### Pending attributes

If you want to utilize the scopes to create models in the "same scope", you should use the `withAttributes` method.

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
public function scopeDraft(Builder $query): void
{
$query->withAttributes([
'hidden' => true,
]);
}
}

It will add the specified attributes to newly created models:

// Create a post with `hidden` set to `true`
$draft = Post::draft()->create(['title' => 'WIP article']);

The `withAttributes` method also adds the specified attributes as constraints. This allows to use the same scope for querying without any additional `where` calls.

// Retrieve the "hidden" posts
$drafts = Post::draft()->get();

<a name="comparing-models"></a>
## Comparing Models

Expand Down