Таким образом, отношение belongsToMany является отношением «многие ко многим», поэтому требуется сводная таблица
Например, у нас есть таблица users
таблица roles
и сводная таблица user_roles
.
user_id
таблица имеет два столбца: user_id
, foo_id
… foo_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) {}