在多对多关系中设置枢轴 table 中的 属性
Setting property in pivot table in many to many relation
我已经在 Vapor 4 中通过枢轴 table LocaleSite
设置了多对多关系 Locale <-> Site。这很有效,我可以将 Locale
附加到 Site
反之亦然。
在 Pivot table 中,我添加了一个 属性 .sortOrder
:
final class LocaleSite : Model {
static let schema = "locale+site"
struct FieldKeys {
static var createdAt: FieldKey { "created_at" }
static var updatedAt: FieldKey { "updated_at" }
static var deletedAt: FieldKey { "deleted_at" }
static var locale: FieldKey { "localeID" }
static var site: FieldKey { "siteID" }
static var sortOrder: FieldKey { "sortOrder" }
}
@ID
var id: UUID?
@Timestamp(key: FieldKeys.createdAt, on: .create)
var createdAt: Date?
@Timestamp(key: FieldKeys.updatedAt, on: .update)
var updatedAt: Date?
@Timestamp(key: FieldKeys.deletedAt, on: .delete)
var deletedAt: Date?
@Parent(key: FieldKeys.locale)
var locale: Locale
@Parent(key: FieldKeys.site)
var site: Site
@Field(key: FieldKeys.sortOrder)
var sortOrder: Int
附加区域设置数组时
for locale in locales {
let _ = site.$locales.attach(locale, on: database)
}
我想将 .sortOrder
设置为某个值,在附加时在同一个循环中(可能通过附加功能?),但是找不到如何 在文档中。
(目前唯一的解决方法是在附加后查询我的站点或语言环境,并通过与枢轴 table 的关系设置 .sortOrder
。非常低效...)
添加了包含一些 Calebs 答案的代码示例(参见评论)
static func createStdData (site: Site, database : Database) -> EventLoopFuture<Void> {
return Locale.allLocale(database: database).map { locales in
var order = 0
for locale in locales {
let _ = site.$locales.attach(locale, on: database, edit: { pivot in
pivot.sortOrder = order
})
order += 1
}
}
}
添加编辑:后,我收到以下错误:
No exact matches in call to instance method 'attach'
检查 Vapor 源我看到有一个,但显然语法可能不完全正确...
我也试过:
let _ = site.$locales.attach(locale, on: database, edit: (LocaleSite){ pivot in
pivot.sortOrder = order
})
但我得到:
Type of expression is ambiguous without more context
您要将 .sortOrder
属性 分配给什么值将改变您想要设置该值的方式。根据您的问题,我将假设每个枢轴的 .sortOrder
比上一个大 1
。
为此,在开始循环之前,我们首先必须保存最后一个数据透视表。这相当简单:
let last = LocaleSite.query(on: database).sort(\.$sortOrder, .descending).first()
此查询会将结果从最高 .sortOrder
排序到最低,因此第一个将具有最高值。我们现在可以映射该结果。如果我们得到一个模型,我们将基于它的新 .sortOrder
值;否则,我们将从 0
.
开始
let sortOrder = last.map { pivot in
return pivot?.sortOrder ?? 0
}
现在我们将对结果调用 .flatMap
。在 .flatMap
闭包中,我们将迭代要使用 Array.map
插入的 Locale
模型,并将每个 Locale
附加到站点。现在,.attach
方法有 a handy closure 可以传入,您可以使用它来编辑新的数据透视模型,然后再将它们插入数据库。我们将使用该闭包来设置枢轴的 .sortOrder
值。
sortOrder.flatMap { order in
locales.enumerated().map { offset, locale in
site.$locales.attach(locale, on: database, { pivot in
pivot.sortOrder = (order + 1) + offset
})
}.flatten(on: database.eventLoop)
}
* 所有代码都是从我脑海中浮现出来的,未经测试,因此可能需要修改才能正常工作
我已经在 Vapor 4 中通过枢轴 table LocaleSite
设置了多对多关系 Locale <-> Site。这很有效,我可以将 Locale
附加到 Site
反之亦然。
在 Pivot table 中,我添加了一个 属性 .sortOrder
:
final class LocaleSite : Model {
static let schema = "locale+site"
struct FieldKeys {
static var createdAt: FieldKey { "created_at" }
static var updatedAt: FieldKey { "updated_at" }
static var deletedAt: FieldKey { "deleted_at" }
static var locale: FieldKey { "localeID" }
static var site: FieldKey { "siteID" }
static var sortOrder: FieldKey { "sortOrder" }
}
@ID
var id: UUID?
@Timestamp(key: FieldKeys.createdAt, on: .create)
var createdAt: Date?
@Timestamp(key: FieldKeys.updatedAt, on: .update)
var updatedAt: Date?
@Timestamp(key: FieldKeys.deletedAt, on: .delete)
var deletedAt: Date?
@Parent(key: FieldKeys.locale)
var locale: Locale
@Parent(key: FieldKeys.site)
var site: Site
@Field(key: FieldKeys.sortOrder)
var sortOrder: Int
附加区域设置数组时
for locale in locales {
let _ = site.$locales.attach(locale, on: database)
}
我想将 .sortOrder
设置为某个值,在附加时在同一个循环中(可能通过附加功能?),但是找不到如何 在文档中。
(目前唯一的解决方法是在附加后查询我的站点或语言环境,并通过与枢轴 table 的关系设置 .sortOrder
。非常低效...)
添加了包含一些 Calebs 答案的代码示例(参见评论)
static func createStdData (site: Site, database : Database) -> EventLoopFuture<Void> {
return Locale.allLocale(database: database).map { locales in
var order = 0
for locale in locales {
let _ = site.$locales.attach(locale, on: database, edit: { pivot in
pivot.sortOrder = order
})
order += 1
}
}
}
添加编辑:后,我收到以下错误:
No exact matches in call to instance method 'attach'
检查 Vapor 源我看到有一个,但显然语法可能不完全正确...
我也试过:
let _ = site.$locales.attach(locale, on: database, edit: (LocaleSite){ pivot in
pivot.sortOrder = order
})
但我得到:
Type of expression is ambiguous without more context
您要将 .sortOrder
属性 分配给什么值将改变您想要设置该值的方式。根据您的问题,我将假设每个枢轴的 .sortOrder
比上一个大 1
。
为此,在开始循环之前,我们首先必须保存最后一个数据透视表。这相当简单:
let last = LocaleSite.query(on: database).sort(\.$sortOrder, .descending).first()
此查询会将结果从最高 .sortOrder
排序到最低,因此第一个将具有最高值。我们现在可以映射该结果。如果我们得到一个模型,我们将基于它的新 .sortOrder
值;否则,我们将从 0
.
let sortOrder = last.map { pivot in
return pivot?.sortOrder ?? 0
}
现在我们将对结果调用 .flatMap
。在 .flatMap
闭包中,我们将迭代要使用 Array.map
插入的 Locale
模型,并将每个 Locale
附加到站点。现在,.attach
方法有 a handy closure 可以传入,您可以使用它来编辑新的数据透视模型,然后再将它们插入数据库。我们将使用该闭包来设置枢轴的 .sortOrder
值。
sortOrder.flatMap { order in
locales.enumerated().map { offset, locale in
site.$locales.attach(locale, on: database, { pivot in
pivot.sortOrder = (order + 1) + offset
})
}.flatten(on: database.eventLoop)
}
* 所有代码都是从我脑海中浮现出来的,未经测试,因此可能需要修改才能正常工作