hasOne с нулевым значением в laravel не работает - PullRequest
0 голосов
/ 04 февраля 2020

У меня есть таблица клиентов, в которой есть поле с именем 'policy_id', где policy_id указывает на таблицу политик. Это нулевое поле, ie. Некоторые клиенты могут не иметь политики. У меня есть код отношения, подобный этому в Customer. php

public function policy() {
    return $this->hasOne('App\Models\Policy', "id", "policy_id");
}

Но когда я выдаю запрос на поиск, я получаю ошибку, подобную этой:

Illuminate\Database\Eloquent\ModelNotFoundException: No query results for model [App\Models\Policy]

Если я изменяю функцию например:

public function policy() {
    if ($this->getAttribute('policy_id')) {
        return $this->hasOne('App\Models\Policy', "id", "policy_id");
    } else {
        return null
    }
}

Но я получаю сообщение об ошибке:

Call to a member function getRelationExistenceQuery() on null

Вот мой код поиска:

    $c = new Customer();
    return Customer::doesntHave('policy')->orWhere(function (Builder $query) use ($req) {
        $query->orWhereHas('policy', function (Builder $query) use ($req) {
            $p = new Policy();
            $query->where($req->only($p->getFillable()))
                ->orWhereBetween("policy_period_from", [$req->policy_period_start_from, $req->policy_period_start_to])
                ->orWhereBetween("policy_period_to", [$req->policy_period_end_from, $req->policy_period_end_to])
                ->orWhereBetween("payment_date", [$req->payment_date_from, $req->payment_date_to]);
        });
    })->where($req->only($c->getFillable()))->get();

Я что-то упустил или Есть ли другие способы сделать это?

PS: во время отладки вышеуказанный код поиска возвращается успешно, но исключение происходит где-то внутри Laravel после вызова prepareResponse.

Заранее спасибо.

Ответы [ 3 ]

1 голос
/ 04 февраля 2020

Прежде всего, вы поместили неправильные параметры.

$this->belongsTo('App\Models\Policy', "FK", "PK");

public function policy() {
    return $this->belongsTo('App\Models\Policy','policy_id', 'id');
}

И для null значения policy_id вы можете использовать withDefault();

public function policy() {
    return $this->belongsTo('App\Models\Policy','policy_id', 'id')->withDefault([
        'name' => 'test'
    ]);;
}
0 голосов
/ 04 февраля 2020

есть ряд проблем, но вы можете указать пространство имен и класс обеих ваших моделей - Customer и Policy. По умолчанию модели, которые вы создаете с помощью php artisan make:model, будут использовать пространство имен \ App, например, \ App \ Customer и \ App \ Policy. Просто дважды проверьте это. Кроме того, что касается отношений, если соблюдены Laravel соглашения, вы можете просто:

В модели Customer

public function policy() {
    return $this->belongsTo(Policy::class);
}

В модели Policy

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

из, если несколько клиентов могут быть под одной политикой

public function customers() {
    return $this->hasMany(Customer::class);
}

Удачи

0 голосов
/ 04 февраля 2020

return $ this-> hasOne ('App \ ModelName', 'foreign_key', 'local_key');

Измените порядок, поместите Foreign_key policy_id перед id

В вашей модели клиента вам нужно использовать метод метод :

public function policy() {
    return $this->belongsTo('App\Models\Policy', "policy_id", "id");
}

А в вашей модели политики используйте hasOne :

public function customer() {
    return $this->hasOne('App\Models\Customer', "policy_id", "id");
}
...