新しいGrails2.1.0アプリケーションでスケジューリング機能を作成しています。私はRubyonRailsプロジェクトから移行しているので、クエリ戦略の多くはRailsスタイルから派生しています。私は次のドメインクラスを持っています:
Schedule.groovy
class Schedule {
// Number of minutes between available appointment slots
int defaultAppointmentInterval
Time officeOpenStart
Time officeOpenEnd
Time lunchStart
Time lunchEnd
static hasMany = [inventorySlots: InventorySlot]
static constraints = {
// long validation rules
}
def boolean isAvailableAt(Date dateTime) {
def isAvailable = true
if (inventorySlots.isEmpty()) {
isAvailable = false
} else if (inventorySlotsSurroundingTime(dateTime).isEmpty()) {
isAvailable = false
}
isAvailable
}
def inventorySlotsSurroundingTime(Date dateTime) {
InventorySlot.surroundingTime(dateTime) {
and {
inventorySlot.schedule = this
}
}
}
}
InventorySlot.groovy
class InventorySlot {
Date startTime
static belongsTo = [schedule: Schedule]
static constraints = {
startTime nullable: false, blank: false
}
static mapping = {
tablePerHierarchy true
schedule lazy: false
}
static namedQueries = {}
def static surroundingTime(Date time) {
[UnboundedInventorySlot.surroundingTime(time), BoundedInventorySlot.surroundingTime(time)].flatten()
}
def endTime() {
return ((BoundedInventorySlot) this).endTime?: (UnboundedInventorySlot (this)).endTime()
}
}
UnboundedInventorySlot.groovy
class UnboundedInventorySlot extends InventorySlot {
static namedQueries = {
// surroundingTime { time ->
// le 'startTime', time
// ge 'startTime', time - 1
// }
}
@Override
def static surroundingTime(Date time) {
findAllByStartTimeLessThanEqualsAndStartTimeGreaterThanEquals(time, time - 1)
}
def Date endTime() {
def endTime
// If the office closing is defined, use that, otherwise use tonight @ 23:59:59
endTime = schedule?.officeOpenEnd?: new DateTime(startTime + 1).withTimeAtStartOfDay().plusSeconds(-1).toDate()
return endTime
}
}
BoundedInventorySlot.groovy
class BoundedInventorySlot extends InventorySlot {
Date endTime
static constraints = {
endTime nullable: false, blank: false, validator: {val, obj ->
if (val.date != obj.startTime.date) { return ["invalid.differentDate", val.date] }
}
}
static namedQueries = {
// surroundingTime { time ->
// le 'startTime', time
// ge 'endTime', time
// }
}
@Override
def static surroundingTime(Date time) {
findAllByStartTimeLessThanEqualsAndEndTimeGreaterThanEquals(time, time)
}
@Override
def Date endTime() {
endTime
}
}
私がやりたいのは、Schedule#isAvailableAt(Date)メソッドを次のように実装することです。
def boolean isAvailableAt(Date dateTime) {
def isAvailable = true
if (inventorySlots.isEmpty()) {
isAvailable = false
} else if (inventorySlots.surroundingTime(dateTime).isEmpty()) {
isAvailable = false
}
isAvailable
}
inventorySlots.surroundingTime()
呼び出しは基本的に、InventorySlot.surroundingTime()
InventorySlotsのユニバースにクエリを実行する代わりに、スケジュールインスタンスに関連付けられたインスタンスのみを事前にフィルタリングします。これはRailsで非常に一般的ですが、Grailsで「連鎖クエリ」または「コレクションクエリ」を検索しても、適切なドキュメントが提供されないようです。助けてくれてありがとう。