Laravel принадлежит отношениям ToMany, определяющим локальный ключ на обеих таблицах

Таким образом, отношение belongsToMany является отношением «многие ко многим», поэтому требуется сводная таблица

Например, у нас есть таблица users таблица roles и сводная таблица user_roles .

user_id таблица имеет два столбца: user_id , foo_idfoo_id ссылающиеся на id в таблице ролей.

Чтобы сделать это, мы пишем следующее в user красноречивой модели:

return $this->belongsToMany('Role', 'user_roles', 'user_id', 'foo_id');

Теперь это ищет поле id в таблице users и соединяет его с полем user_roles таблице user_roles .

Проблема заключается в том, что я хочу указать другое поле, отличное от id для соединения в таблице users . Например, у меня есть bar_id в таблице users, которую я хочу использовать в качестве local key для соединения с user_id

Из документации laravel не ясно, как это сделать. В других отношениях, таких как hasMany и belongsTo мы можем указать local key и foriegn key но не по какой-либо причине.

Я хочу, чтобы local key в таблице users был bar_id а не только id .

Как я могу это сделать?

Я предполагаю, что id является первичным ключом в вашей модели User , поэтому нет способа сделать это с помощью методов Eloquent, потому что belongsToMany использует $model->getKey() для получения этого ключа.

Таким образом, вам нужно создать настраиваемое отношение, которое распространяется на belongsToMany которое будет делать то, что вам нужно.

Быстро предположить, что вы можете попробовать: (не тестировался, но не будет работать с уверенной загрузкой)

 // User model protected function setPrimaryKey($key) { $this->primaryKey = $key; } public function roles() { $this->setPrimaryKey('desiredUserColumn'); $relation = $this->belongsToMany('Role', 'user_roles', 'user_id', 'foo_id'); $this->setPrimaryKey('id'); return $relation; } 

Это недавно добавленная функция. Мне пришлось обновиться до 4.1, потому что я тоже искал это.

Из документации API :

 public BelongsToMany belongsToMany(string $related, string $table = null, string $foreignKey = null, string $otherKey = null, string $relation = null) 

Параметры $otherKey и $relation были добавлены в 4.1. Используя параметры $foreignKey и $otherKey вы можете указать ключи с обеих сторон отношения.

Лучший способ – установить первичный ключ.

 class Table extends Eloquent { protected $table = 'table_name'; protected $primaryKey = 'local_key'; 

attribToMany позволяет определить имя полей, которые будут хранить ключи che в сводной таблице, но метод всегда вставляет значения первичного ключа в эти поля.

Вы должны:

  • define в методе принадлежит для таблицы и столбцов;

  • затем используя protected $ primaryKey = 'local_key'; вы можете выбрать хранилище значений.

Недавно я столкнулся с той же проблемой, когда мне понадобилась связанная таблица, в которой использовались идентификаторы, чтобы связать две таблицы вместе, которые не были основными ключами. В основном я создал копию моей модели, которая моделирует сводную таблицу и устанавливает первичный ключ в значение, которое я хотел использовать. Я попытался создать экземпляр модели, установил первичный ключ, а затем передал это отношение, но Laravel не уважал первичный ключ, который я установил (используя метод -> setPrimaryKey () выше).

Создание копии модели и настройка первичного ключа чувствуют себя немного «взломанными», но в итоге они работают так, как должны, и поскольку модели таблиц Pivot, как правило, очень малы, я не вижу в этом никаких проблем в будущем.

Хотелось бы увидеть третий ключевой вариант, доступный в следующем выпуске Laravel, который позволит вам получить более конкретную информацию о вашей ссылке.

На Laravel 5,

  public function categories() { return $this->belongsToMany(Category::class,'service_categories','service_id','category_id', 'uuid', 'uuid'); } 

Из исходного кода:

  public function belongsToMany($related, $table = null, $foreignPivotKey = null, $relatedPivotKey = null, $parentKey = null, $relatedKey = null, $relation = null) {}