admin管理员组文章数量:1332107
In Laravel Eloquent, I am using select
to get specific columns only in a collection:
$tickets = Tickets
::select('id', 'title', 'date') // so only these columns
->limit(100)
->get();
but I also have a custom attribute in the "Ticket" model that uses different columns:
public function getStatusAttribute() {
if ($this->payment == $this->total & $this->active) {
return "paid";
} else {
return "unpaid";
}
}
then when doing
foreach ($tickets as $ticket) {
echo $ticket->id
. $ticket->title
. $ticket->date
. $ticket->status // <- custom attribute
;
}
as I tell query to only select 'id', 'title', 'date', at what point Laravel gets additional columns from database (specifically the 'payment', 'total', 'active')? Does it runs additional queries for each row?
I only see main query (without columns from custom attribute being selected), when trying to log them either with dump(DB::getQueryLog());
or directly in MySQL:
SET GLOBAL log_output = "FILE";
SET GLOBAL general_log_file = "c:/AAA/logfile.log";
SET GLOBAL general_log = 'ON';
So I do not understand at what point Laravel gets additional columns from the database? My concern is to have 1 query and not 100.
In Laravel Eloquent, I am using select
to get specific columns only in a collection:
$tickets = Tickets
::select('id', 'title', 'date') // so only these columns
->limit(100)
->get();
but I also have a custom attribute in the "Ticket" model that uses different columns:
public function getStatusAttribute() {
if ($this->payment == $this->total & $this->active) {
return "paid";
} else {
return "unpaid";
}
}
then when doing
foreach ($tickets as $ticket) {
echo $ticket->id
. $ticket->title
. $ticket->date
. $ticket->status // <- custom attribute
;
}
as I tell query to only select 'id', 'title', 'date', at what point Laravel gets additional columns from database (specifically the 'payment', 'total', 'active')? Does it runs additional queries for each row?
I only see main query (without columns from custom attribute being selected), when trying to log them either with dump(DB::getQueryLog());
or directly in MySQL:
SET GLOBAL log_output = "FILE";
SET GLOBAL general_log_file = "c:/AAA/logfile.log";
SET GLOBAL general_log = 'ON';
So I do not understand at what point Laravel gets additional columns from the database? My concern is to have 1 query and not 100.
Share Improve this question asked Nov 26, 2024 at 22:48 LannalinaLannalina 31 bronze badge 1- Just advice - if this attribute MATTER - check real fields for null and throw exception on null. Queries will mot perform as answered below. – Maksim Commented Nov 27, 2024 at 1:13
2 Answers
Reset to default 0The status attribute is never queried from the DB. The value is calculated after the query is run when you request the value using $ticket->status
or when the instance of the model is serialised.
If you have retrieved your instance using your query builder code:
Tickets::select('id', 'title', 'date') // so only these columns
->limit(100)
->get();
Then I would expect your getStatusAttribute
to return "paid"
but you need to understand why:
The query will result in an instance where
$this->payment
is NULL
$this->total
is NULL
and $this->active
is NULL
Because you're not getting those values from the database.
When you call $this->payment == $this->total & $this->active
You're saying NULL == NULL & NULL
Note: Be careful with your logic here as NULL & NULL
will evaluate to 0
whereas NULL && NULL
will evaluate to false
Therefore you need to either be more defensive in your getStatusAttribute
logic. You could consider returning NULL if the required columns are all NULL but you probably want to make sure those values are always queried.
$tickets = Tickets::select('id', 'title', 'date', 'payment', 'total', 'active')
->limit(100)
->get();
The above would do the job but the overhead of querying columns you don't explicitly need is negligible so you could just drop the select entirely and use:
$tickets = Tickets::limit(100)
->get();
If there are values in there you want to prevent the model showing when serialised I would recommend using the Eloquent Model's "hidden" property
hope my solution solves your problem. To ensure the status attribute works correctly, modify your query to include the columns needed for the accessor:y and avoid additional queries.
$tickets = Tickets::select('id', 'title', 'date', 'payment', 'total', 'active')
->limit(100)
->get();
This way, all the necessary data for the custom attribute is fetched in the initial query.
Thanks
本文标签:
版权声明:本文标题:What queries will run, when Laravel Eloquent use select, and model have custom attribute? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742273998a2444846.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论