我有几个型号的日期字段的名称相同,如下所示:

final class ModelA: Model {

static let schema = "model_a"

@Timestamp(key: "modification_date", on: .update, format: .unix)
var modificationDate: Date?

}

final class ModelB: Model {

static let schema = "model_b"

@Timestamp(key: "modification_date", on: .update, format: .unix)
var modificationDate: Date?

}

final class ModelC: Model {

static let schema = "model_c"

@Timestamp(key: "modification_date", on: .update, format: .unix)
var modificationDate: Date?

}

在我的代码中的某个点上,我希望获得最近更改的模型.所以我可以写下这样的东西:

func getRecentlyChangedModelAs(on db: Database) async throws -> [ModelA] {
   return try await ModelA.query(on: db)
                          .group(.and) { group in
                             group.filter(\.$modificationDate != nil)
                             group.filter(\.$modificationDate > Date.now.addingTimeInterval(TimeInterval(-3600)))
                          }
                          .all()
}

func getRecentlyChangedModelBs(on db: Database) async throws -> [ModelB] {
   return try await ModelB.query(on: db)
                          .group(.and) { group in
                             group.filter(\.$modificationDate != nil)
                             group.filter(\.$modificationDate > Date.now.addingTimeInterval(TimeInterval(-3600)))
                          }
                          .all()
}

func getRecentlyChangedModelCs(on db: Database) async throws -> [ModelC] {
   return try await ModelC.query(on: db)
                          .group(.and) { group in
                             group.filter(\.$modificationDate != nil)
                             group.filter(\.$modificationDate > Date.now.addingTimeInterval(TimeInterval(-3600)))
                          }
                          .all()
}

正如您所看到的,有很多代码重复.为了避免这种情况,我try 使用协议和通用查询:

protocol ModifiableModel: Model, Content {
    var modificationDate: Date? { set get }
}

final class ModelA: ModifiableModel {

static let schema = "model_a"

@Timestamp(key: "modification_date", on: .update, format: .unix)
var modificationDate: Date?

}

etc...

func getRecentlyChangedModel<T: ModifiableModel>(on db: Database) async throws -> [T] {
   return try await T.query(on: db)
                     .group(.and) { group in
                        group.filter(\.$modificationDate != nil) // Errors: 'nil' is not compatible with expected argument type 'KeyPath<Right, RightField>', Generic parameter 'RightField' could not be inferred
                        group.filter(\.$modificationDate > Date.now.addingTimeInterval(TimeInterval(-3600))) // Errors: Cannot convert value of type 'Date' to expected argument type 'KeyPath<Right, RightField>', No exact matches in call to instance method 'filter'
                      }
                      .all()

遗憾的是,这会在查询的过滤器中导致错误.我不太理解这些错误,但我发现没有过滤器,一切都编译得很好.我最好的猜测是,这些错误与我试图在筛选器中使用的关键路径有关.

有人知道问题出在哪里或如何解决吗?或者,有没有其他方法可以用来避免这种代码重复?任何帮助都将不胜感激!

推荐答案

我认为这种方法行不通.通过在筛选器中输入T得到的错误消息中有线索,如下所示:

group.filter(\T.$modificationDate != nil)

给出错误:

无法推断泛型参数""field"",并且类型""T""的值没有成员""$ModifiationDate""

这个问题是因为filter需要一个用字段包装器定义的属性(在本例中是@Timestamp).然而,正如您可能已经发现的那样,放置:

protocol ModifiableModel {
    @Timestamp(key: "modification_date", on: .update, format: .unix)
var modificationDate: Date?
}

会导致一条错误消息,提示您不能在协议中使用包装定义变量.由于你的方法取决于情况,我认为它不可能奏效.

编辑:

我忘了补充,您应该能够将代码简化为只根据值进行筛选.应该没有任何需要先测试非零.try :

func getRecentlyChangedModelAs(on db: Database) async throws -> [ModelA] {
   return try await ModelA.query(on: db)
                          .filter(\.$modificationDate > Date.now.addingTimeInterval(TimeInterval(-3600)))
                          .all()
}

如果您得到了错误的结果,那么请判断您的迁移,以确保这里没有错误.

Swift相关问答推荐

如何在Swift 中创建移动的uil标签?

启用完成并发判断以及如何解决警告(续)

计算 CoreData 中所有唯一对象的数量?

使用`JSONSerialiser`时,省略通用可选项

使用View()和List()无法显示影子

Swift 并发任务与调度队列线程:是什么决定同时运行多少任务?

Firebase removeObserver 在 Swift 5 中不起作用

LeetCode 249. 分组移位字符串

从 Swift 列表中的行中检索值

SwiftUI Preview 不适用于 Core Data

Swift 2.0 方法不能标记为@objc,因为参数的类型不能在 Objective-C 中表示

在 Swift 中获取双精度的小数部分

使 struct 可散列?

Swift 协议只能设置?

iOS:检测设备是否为 iPhone X 系列(无框)

如何轻松删除领域中的所有对象

Swift:如何从函数返回类类型

如何在 Swift 中遍历 struct 属性?

如何在 Swift 中将 NSURL 转换为字符串

自定义 Google 登录按钮 - iOS