fefe
fefe

Reputation: 9055

Laravel Scout map in toSearchableArray relationship fields

Is it possible to map in toSearchableArray relationship fields as well. What I mean, having User model I try to search in related model fields as well like;

/**
 * Get the indexable data array for the model.
 *
 * @return array
 */
public function toSearchableArray()
{
    return [
        'name' => $this->name,
        'plz' => $this->account->zip,
    ];
}

/**
 * @return HasOne
 */
public function account(): HasOne
{
    return $this->hasOne(Member::class);
}

In controller searching after results

    if($request->has('s')) {
        $founds = User::search($request->get('s'))->get();
    }

will throw Attempt to read property "zip" on null

I do not really find any infos in documentation related to this question

Upvotes: 1

Views: 1400

Answers (1)

bhucho
bhucho

Reputation: 3420

I do have two ways to do it of which I consider one of them as crude.

Method 1:

Here's an example implementation where you're searching all of one model and then a relationship (accounts)

public function toSearchableArray()
{
    $array = $this->toArray();

    $array = $this->transform($array);

    $array['country'] = $this->countries->map(function ($data) {
        return $data['name'] ?? '';
    })->toArray();

    return $array;
}

Method 2:

public function toSearchableArray()
    {
        $array = $this->toArray();
 
        // Customize array...
        $array = [
            'user_name' => $this->user_name,
            'country' => $this->getCountryNameById($this->country_id),
            ...
        ];
 
        return $array;
    }

where relationship is defined in helpers or you can make a separate trait and import it in model with method. Here relationship for country is defined within the model as

//Get Country name By id
function getCountryNameById($id) {
    $country = \App\Country::select('name')->find($id);
    return $country->name ?? '';
}

Upvotes: 1

Related Questions