Связь между таблицей «многие ко многим» и другой таблицей «один ко многим» - PullRequest
0 голосов
/ 16 октября 2018

Доброе утро всем,

Прежде всего, чтобы сказать, что я использую Laravel, следовательно, Eloquent ORM, но я думаю, что это больше проблема чисто реляционных баз данных (или нет), поэтому яупомяните об этом здесь.

Некоторое время я устанавливал связь между many-to-many таблицей и таблицей один-ко-многим.

Существует 4 таблицы:

  • 'machines' (id, имя, ...)
  • 'products' (id, name, ...)
  • 'machine_products' (id, machine_id, product_id, цена).
  • «ограничения» (id, machine_product_id, day, begin_hour, end_hour)

Для данной машины и продукта, в частности, существует N ограничений.

Пока, я думаю, что все в порядке, но начинаются сомнения, когда я хочу перевести это в модели Laravel.

В принципе, у нас были бы эти три модели:

  • Машина
  • Продукт
  • Ограничение
  • (MachineProduct ??? Это не обязательно в теории)

Nкак правило, many-to-many модели не нужно делать, так как к ним можно получить доступ через одну из двух основных моделей.В этом случае с Machine или Product мы могли бы получить доступ к сводной таблице machine_products.

Проблема возникает, когда из экземпляра Machine или Product, к которому я хочу получить доступ, черезКрасноречивый, restrictions.Таким же образом, я не знаю, как получить доступ к Machine или Product через экземпляр restrictions.

Один вариант, который я выбрал на данный момент, это, хотяэто только решает первую проблему:

Restriction::find(Machine::find(1)->products()->first()->pivot->id);

Мы могли бы предложить более элегантное и практичное решение, чтобы получить ограничения от продукта / машины и обратно?

Спасибо!

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

Я хочу что-то вроде этого:

Machine::find(1)->products()->first()->restrictions или что Product::find(1)->machines()->first()->[pivot?]->restrictions.

Я также хотел бы иметь возможностьсделать это: Restriction::find(1)->[pivot?]->machine (или продукт)

Вот три модели:

class Machine extends Model
{
    public function products()
    {
        return $this->BelongsToMany('App\Product', 'machine_products')->withPivot('id','price');
   }
}


class Product extends Model
{  
    public function machines()
    {
        return $this->BelongsToMany('App\Machine', 'machine_products')->withPivot('price');
    }

}


class Restriction extends Model
{
    // Nothing
}

1 Ответ

0 голосов
/ 16 октября 2018

Обычно не рекомендуется (или необходимо) иметь столбец id в сводной таблице.

Я бы удалил его и настроил таблицу restrictions: id, machine_id, product_id, ...

Это выполняет ваше второе требование: Restriction::find(1)->machine

Обратное направление все еще остается проблемой.Я думаю, что просто нет элегантного решения для этого:

Restriction::where('machine_id', $machine_id)
    ->where('product_id', $product_id)
    ->get();

Вы можете упростить его с помощью области:

class Restriction extends Model {
    public function scopeByIds($query, $machine_id, $product_id) {
        $query->where('machine_id', $machine_id)
            ->where('product_id', $product_id);
    }
}

Restriction::byIds($machine_id, $product_id)->get();
...