guru
guru

Reputation: 307

How do I perform Eloquent queries on results from my own method on a Model?

I have 2 models, on for Listing and one for State. The relationship on Listing is:

return $this->belongsTo('App\State');

I have my own method on the Listing model to return items based on distance:

public static function getClosest($lat, $lng, $distance)
{
    $results = Listing::select('id', 'name', 'address', 'suburb', 
        'postcode', 'phone', 'url')
        ->selectRaw('( 6371 * acos( cos( radians(?) ) *
            cos( radians( ST_X(position) ) )
            * cos( radians( ST_Y(position) ) - radians(?)
            ) + sin( radians(?) ) *
            sin( radians( ST_X(position) ) ) )
            ) AS distance', [$lat, $lng, $lat])
        ->havingRaw("distance < ?", [$distance])
        ->orderBy('distance', 'asc')
        ->get();

    return collect($results);
}

In my ListingController I want to return the name of the state for each item returned by my results.

If I get the results as:

$listings = Listing::all();

It works, but if I use my custom method it doesn't:

$listings = Listing::getClosest($request['lat'], $request['lng'],1000);

The way I'm trying to get the state is with:

foreach ($listings as $item) {
        return $item->state->short_name;

Why does it work with I get all but not when I get the results with my custom method?

Upvotes: 0

Views: 38

Answers (1)

TsaiKoga
TsaiKoga

Reputation: 13394

Because you loss the foreign_key state_id. and your selectRaw cover your select.

Remember you need to select your foreign_key(state_id), so that laravel can find its relationship.

Try to do it like this:

public static function getClosest($lat, $lng, $distance)
{
    return Listing::select(\DB::raw('( 6371 * acos( cos( radians(?) ) *
                       cos( radians( ST_X(position) ) )
                       * cos( radians( ST_Y(position) ) - radians(?)
                       ) + sin( radians(?) ) *
                       sin( radians( ST_X(position) ) ) )
                     ) AS distance', [$lat, $lng, $lat]), 
                     'id', 'name', 'address', 'suburb', 'postcode', 'phone', 'url','name', 'state_id')
        ->havingRaw("distance < ?", [$distance])
        ->orderBy('distance', 'asc')
        ->get();
}

Upvotes: 1

Related Questions