Поработав немного над этим, я нашел ответ.
Реализацию удобных функций Fluent siblings
можно найти в этом выделенном сегменте на GitHub . Я скопировал это ниже для ясности обсуждения:
extension Model {
...
/// Free implementation where pivot constraints are met.
/// See `Model.siblings(_:_:)`.
public func siblings<Related, Through>(
related: Related.Type = Related.self,
through: Through.Type = Through.self
) -> Siblings<Self, Related, Through>
where Through.Right == Self, Through.Left == Related
{
return siblings(Through.rightIDKey, Through.leftIDKey)
}
/// Free implementation where pivot constraints are met.
/// See `Model.siblings(_:_:)`.
public func siblings<Related, Through>(
related: Related.Type = Related.self,
through: Through.Type = Through.self
) -> Siblings<Self, Related, Through>
where Through.Left == Self, Through.Right == Related
{
return siblings(Through.leftIDKey, Through.rightIDKey)
}
}
Проблема, я полагаю, заключается в том, что мое желаемое использование было неоднозначным. Первая функция в приведенном выше фрагменте используется, когда Self
- это правый тип оси, а Related
- левый тип. Аналогично, вторая функция используется, когда имеет место обратное.
Поскольку я использовал тип Siblings<X, X, XPivot>
, Свифт не смог определить, какая функция лучше, так как условия были выполнены для каждой.
Чтобы исправить это, я реализовал собственное расширение:
extension Model {
public func childrenSiblings<Through>(
through: Through.Type = Through.self
) -> Siblings<Self, Self, Through>
where Through.Left == Self, Through.Right == Self
{
return siblings(Through.leftIDKey, Through.rightIDKey)
}
public func parentSiblings<Through>(
through: Through.Type = Through.self
) -> Siblings<Self, Self, Through>
where Through.Left == Self, Through.Right == Self
{
return siblings(Through.rightIDKey, Through.leftIDKey)
}
}
Я использовал childrenSiblings
, чтобы указать, когда вы ищете детей текущего типа (которые также относятся к тому же типу), и parentSiblings
для поиска родителей текущего типа (того же типа). ). Разница между ними заключается во внутреннем вызове siblings
, где Through.leftIDKey
и Through.rightIDKey
переключаются во второй функции. Это связано с тем, как я структурировал сводную таблицу (т. Е. Левый столбец равен parent_folder_id
, а правый столбец - child_folder_id
).
Использование этих функций аналогично использованию обычных функций siblings
. В моем случае в вопросе, где я отношу Folder
типов к другим Folder
s:
extension Folder {
var subFolders: Siblings<Folder, Folder, FoldersToSubfoldersPivot> {
return childrenSiblings()
}
var superFolders: Siblings<Folder, Folder, FoldersToSubfoldersPivot> {
return parentSiblings()
}
}