I added a custom attribute to my model
public function getTouchedAttribute() { ...
I would like to add this to a query
hasMany()->where('touched', ...)
but obviously this isn't a column in the table.
what is the most elegant way to achieve this behavior?
One option (and probably the better one in terms of performance) would be to mimic the attribute with raw SQL functions. (Can't help you with that because I don't know what touched
does)
The other way is to use filter
on the resulting collection:
$collection = Model::all();
$filtered = $collection->filter(function($model){
return $model->touched == true;
});
I know this is a 4 year old topic (from 2015) but it's still getting traffic from web searches. So I want to share an idea;
You can use Local Query Scopes of Eloquent to define custom where clauses.
As said in documentation:
Local scopes allow you to define common sets of constraints that you may easily re-use throughout your application. For example, you may need to frequently retrieve all users that are considered "popular". To define a scope, prefix an Eloquent model method with scope.
And an example: If you define a custom scope on your model:
public function scopePopular($query)
{
return $query->where('votes', '>', 100);
}
You can use it directly with your model.
App\User::popular()->orderBy('created_at')->get();
So you can define a scopeTouched()
method and implement your logic.
I assume if updated_at not equal to created_at the row is touched here. Of course you can change this behaviour.
public function scopeTouched($query)
{
return $query->where('updated_at', '!=', 'created_at');
}
And use it with your model.
Model::touched()->get();
And of course you can use it with other query builder methods.
Model::touched()->paginate(20);
Model::touched()->orderBy('id', 'DESC')->take(10)->get();
Model::touched()->latest()->first();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With