I've got a fairly simple real estate website with, among a few others, a model for Propertys.
To prevent the display of invalid properties (properties without sufficient data, like a price and lot size) I had a function like the following in my Property model:
app/Models/Property.php
public static function valid() {
return Property::query()
->where("price", "<>", 0)
->where("lot_size", "<>", 0);
}
which I then utilize throughout the website like so:
resources/views/list.blade.php
<ul>
@foreach( Property::valid()->get() as $property )
<li></li>
@endforeach
</ul>
This may not be the most elegant solution, but it worked perfectly for my use case.
The issue is that the client would now like to display on the admin panel next to a property whether the property is valid or not, so that they can open it up to fix it if it's invalid. I don't want to re-implement the logic that defines "valid" in the view of the admin panel because then if we change the definition of "valid" in the future I'll have to update it in multiple places.
Glancing at the documentation for Collections, a Collection supports where, whereIn, and other such features (although not whereExists which could prove problematic) so as a proof-of-concept I wanted to see if I could refactor my valid() function like so:
app/Models/Property.php
protected $appends = ["is_valid"];
public static function valid() {
return Property::checkValid(Property::query());
}
public function getIsValidAttribute() {
return Property::checkValid(collect($this))->count() > 0;
}
private static function checkValid($query) {
return $query->where("price", "<>", 0)
->where("lot_size", "<>", 0);
}
Looks reasonable, right? If I call valid() then it passes a QueryBuilder and filters in the database, or once given a Property it will perform identical checks on a single instance and append the result to any API queries as is_valid...
Except it caused an infinite loop. The problem is, it's not quite clear where the infinite loop is. I seem to have just tripped a weird section of Laravel's code.
So now I'm looking for two answers:
- Why did this cause an infinite loop?
- What's the proper way to filter by a computed attribute like this?
via Chebli Mohamed
Aucun commentaire:
Enregistrer un commentaire