Laravel принадлежит к многим отношениям только с одним результатом - PullRequest
0 голосов
/ 09 апреля 2019

У меня есть связь между двумя таблицами с таблицей соединений, которая имеет только один результат.

Когда я определяю отношение Laravel employeeToMany, вместо того чтобы возвращать коллекцию только с одним элементом, я хотел бы, чтобы она возвращала только этот элемент.

Есть ли способ смоделировать это в Laravel?

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

[ РЕДАКТИРОВАТЬ ]

Я попытаюсь объяснить, что я хочу, на примере классического пользователя / роли.Помимо таблиц de users и roles, у нас будет сводная таблица users_roles, в которой будут храниться все роли, которые имел пользователь.Пользователь может в любой момент времени иметь только одну активную роль (которая определяется атрибутом active true).

class User {
    function role() {
        return $this->belongsToMany('App\Role')->wherePivot('active', 'true');
    }
}

С этим определением отношений, когда я получаю доступ к $user->role, я получаю коллекцию (только с одним элементом) ролей.Мне бы хотелось, чтобы этот экземпляр роли был напрямую.

Ответы [ 2 ]

2 голосов
/ 09 апреля 2019

Я не знаю, почему вы принадлежите ToMany, если вам нужно только одно отношение, однако следующий код поможет вам:

public function products()
{
    return $this->belongsToMany('App\Product');
}

public function specific_product()
{
    return $this->products()
                ->where('column','value')->first();
}

OR

public function getSpecificProductAttribute()
{
    return $this->products()
                ->where('column','value')->first();
}
0 голосов
/ 27 мая 2019

Я столкнулся с точно такой же проблемой, позвольте мне показать вам, как мне это удалось.

В моем случае, если между материалами и customer_types есть отношение ownToMany, сводная таблица содержит цену материала для определенных типов клиентов, поэтому в сводной таблице столько же записей (цен), сколько и customer_types.

То, что я ожидал: когда запрашивается цена для определенного customer_type, я хочу получить ограниченную цену для этого конкретного customer_type как вложенный элемент .

Что я получил: коллекция только с 1 элементом.

Это то, что у меня было в начале в моей модели:

class Material extends Model
{
    public function customer_types(){
        return $this->belongsToMany('App\CustomerType', 'customertype_material', 'material_id', 'customertype_id')->withPivot('price');
    }
}

Конечно, когда я запрашивал customer_types для определенного customer_type, результат не был ожидаемым:

$resources = Material::with(['customer_types' => function($query) use ($customer_type_id){
                        $query->where('customertype_id', $customer_type_id);
                       }])->get();

Он возвращал модель Material с вложенной коллекцией customer_types с 1 элементом, заставляя меня использовать first () или перебирать 1 элемент.

Решение: Создайте модель, которая расширяет сводную таблицу и добавляет к ней отношение.

Создана новая модель, расширяющая стержень:

use Illuminate\Database\Eloquent\Relations\Pivot;

class CustomertypeMaterial extends Pivot
{
    protected $table    = 'customertype_material';
    protected $fillable = ['price', 'customertype_id', 'material_id'];
}

Теперь в моей Материальной модели добавлена ​​связь, указывающая на эту новую модель:

public function scoped_price(){
    return $this->belongsTo('App\CustomertypeMaterial', 'id','material_id');
}

Наконец запрос загружает это новое отношение:

$resources = Material::with(['scoped_price' => function($query) use ($customer_type_id){
                        $query->where('customertype_id', $customer_type_id);
                       }])->get();

В результате получается модель материала с вложенным в нее элементом scoped_price, который фильтруется по customer_type_id

Я не уверен, что это правильный способ, но он работает на меня.

Надеюсь, это поможет!

...