Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Laravel / Eloquent: Search for rows by value in polymorphed table

I'm stuck at the moment and hope someone can give me a hand. I'm using a polymorphic relation and want to search my database for rows that fulfill conditions in the "parent" and the "child" table.

To get concrete, one small example. Given the following structure I e.g. want to look for a property with price "600" and rooms "3". Is there a way to do that with eloquent?



Tables

Table properties (parent)

  • id
  • price
  • details_type [can be "Apartment" or "Parcel"]
  • details_id

Table apartments (child)

  • id
  • rooms

Table parcels (child)

  • id
  • ... (does not have a "rooms" column)



Relationships

Class Property

public function details() {
  return $this->morphTo();
}

Classes Apartment + Parcel

public function property() {
  return $this->morphMany('Property', 'details')
}




What I tried

A lot, really. But somehow I'm always doing something wrong or missing something. The solutions that, in my opinion should work are either:

Property::with(array('details' => function($query) {
                  $query->where('rooms', 3);
             }));

or

Property::with('details')
        ->whereHas('details', function($query) {
            $query->where('rooms', '=', '3');
        });

But in both cases I get the following FatalError.:

Class name must be a valid object or a string



Has anyone of you already had a similar problem? Thank you very much for any kind of hint.

like image 724
MrSnoozles Avatar asked Sep 10 '25 22:09

MrSnoozles


1 Answers

Let's start with your naming convention:

public function detail() // It relates to a single object
{
    return $this->morphTo();
}

And

public function properties() // It relates to several objects
{
    return $this->morphMany('Property', 'details')
}

Then you would be able to do this:

$properties = Property::whereHas('details', function($q)
{
    $q->where('rooms', '=', '3');
})
->where('price', '=', 600)
->get();

Please note that this will never return a Parcel, since there isn't a parcel with a room.

like image 98
Ronald Hulshof Avatar answered Sep 13 '25 12:09

Ronald Hulshof