Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

PersonalHomePage's avatar

Search multiple models based on one query from a model's scoped Search

I'm trying to implement a string search for one table that is daisy chained to other tables. It should be able to get any value if it exists from any of those tables. I have a customer, invoice, order models/tables. Customer has a fk inside of Invoice and Invoice has a fk inside of Order. So they all have a one-to-many relationship going down the list. For example I search for a customer by name and I would like to be able to get all of that customer's invoices and all of the orders that belong to those invoices.

Here is my Customer model:

class Customer extends Model
{
    use SoftDeletes;
    protected $guarded = [];

    public function scopeSearch($query, $search)
    {
        return $query->where('internal_name', 'LIKE', "%$search%")
            ->orderBy('created_at', 'desc');
    }

    public function invoices()
    {
        return $this->hasMany(Invoice::class);
    }
}

Invoice and order models:

class Invoice extends Model
{
    use softDeletes;

    public function customer()
    {
        return $this->belongsTo(Customer::class);
    }

    public function orders()
    {
        return $this->hasMany(Order::class);
    }
}
class Order extends Model
{
    use SoftDeletes;

    public function invoice()
    {
        return $this->belongsTo(Invoice::class);
    }
}

here is my controller method:

// check if query exists and sanitize it
        if($request->has('q') && $data = $this->sanitizeQuery($request))
        {
            $customers = Customer::with('invoices')->search($data['q'])->get();
            dd($customers);

for the output i get this:

Illuminate\Database\Eloquent\Collection {#1235 ▼
  #items: array:23 [▼
    0 => App\Customer {#1253 ▶}
    1 => App\Customer {#1254 ▶}
    2 => App\Customer {#1255 ▶}
    3 => App\Customer {#1256 ▶}
    4 => App\Customer {#1257 ▶}
    5 => App\Customer {#1258 ▶}
    6 => App\Customer {#1259 ▶}
    7 => App\Customer {#1260 ▶}
    8 => App\Customer {#1261 ▶}
    9 => App\Customer {#1262 ▼
      #guarded: []
      #connection: "mysql"
      #table: "customers"
      #primaryKey: "id"
      #keyType: "int"
      +incrementing: true
      #with: []
      #withCount: []
      #perPage: 15
      +exists: true
      +wasRecentlyCreated: false
      #attributes: array:14 [▶]
      #original: array:14 [▶]
      #changes: []
      #casts: []
      #classCastCache: []
      #dates: array:1 [▶]
      #dateFormat: null
      #appends: []
      #dispatchesEvents: []
      #observables: []
      #relations: array:1 [▼
        "invoices" => Illuminate\Database\Eloquent\Collection {#1224 ▼
          #items: []
        }
      ]
      #touches: []
      +timestamps: true
      #hidden: []
      #visible: []
      #fillable: []
      #forceDeleting: false
    }

I see that there is an empty invoice there, but I have a row in my db with the matching customer_id. How can I get this data and how can I extend this to work for the orders as well?

0 likes
0 replies

Please or to participate in this conversation.