1

我已经通过 Vapor 4 中的数据透视表设置了多对多关系 Locale <-> Site。LocaleSite这是有效的,我可以附加LocaleSite,反之亦然。在数据透视表中,我添加了一个属性.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在附加时在同一个循环中将 设置为某个值(也许通过附加函数?),但在文档中找不到如何。

(目前唯一的解决方法是在附加后查询我的站点或语言环境,并通过与数据透视表设置的关系.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
            }
        }
    }

一旦 edit: 添加我收到以下错误:

调用实例方法“附加”时没有完全匹配

检查蒸气源,我看到有一个,但显然语法可能不完全正确......

我也试过:

let _ = site.$locales.attach(locale, on: database, edit: (LocaleSite){ pivot in
                    pivot.sortOrder = order
                })

但我得到:

在没有更多上下文的情况下,表达式的类型是模棱两可的

4

1 回答 1

2

您要为该.sortOrder属性分配的值将改变您设置该值的方式。根据您的问题,我将假设每个支点的 a.sortOrder1大于上一个。

为此,我们首先必须在开始循环之前保存最后一个枢轴。这是相当直截了当的:

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闭包中,我们将迭代Locale您要插入的模型Array.map并将每个模型附加Locale到站点。现在,该.attach方法有一个方便的闭包,您可以传入该闭包,您可以使用它在将新的数据透视模型插入数据库之前对其进行编辑。我们将使用该闭包来设置枢轴的.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)
}

* 所有代码都是在我脑海中写下的,未经测试,因此可能需要修改才能正常工作

于 2021-01-19T14:32:21.683 回答