My latest invention is a system where you can track waffles in real time at restaurants around the world.
To achieve this, I have a Waffle
which has many Condiments
, any of which may or may not be present
on the Waffle
. Waffle
has the table number
it's currently on, and belongs to a Restaurant
which has many Name
s translated into different language
s.
Technically, I need to get every Waffle
where Waffle.shape == 'square'
and order it by the Restaurant
's Name
where Waffle.Restaurant.Names.language == 'en'
and display whether Condiment.present
is true.
Restaurant.Names = ['language':'en', 'name':'Waffle House'], ['language':'fr', 'name':'Le Waffle House'], ['language':'de', 'name':'Das Waffle House']
Filtered by square shaped ============================ (Ascending order) V Restaurant Table# Syrup Butter Mayo --------------------------------------------------------- Denny's 42 Y Y N Denny's 27 N N N Denny's 11 Y Y N IHOP 10 Y N N IHOP 7 N N N Waffle House 10 Y Y Y
Here's a simplified version of classes:
class Condiment {
int condimentId
boolean present
Waffle waffle
static belongsTo = [Waffle]
}
class Waffle {
int waffleId
int tableNumber
String shape
Restaurant restaurant
static belongsTo = [Restaurant]
static hasMany = [condiments:Condiment]
}
class Restaurant {
int restaurantId
static hasMany = [waffles:Waffle, names:Name]
}
class Name {
String name
String language
static hasMany = [restaurants:Restaurant]
}
I'd like to do this in GORM if possible but HQL is acceptable too. This is with Grails 2.3. Keep in mind this is paginated because there are millions of Waffle
s in the world, if not more!
Criteria based:
def waffles = Waffle.createCriteria().list(offset: 0, max: 100){
eq('shape', 'square')
restaurant{
names{
eq('language', 'en')
order('name', 'asc')
}
}
condiments{
eq('present', true)
}
}
HQL based:
def query = """
select w from Waffles as w \
inner join w.restaurant as r \
inner join w.condiments as c \
inner join r.names as n \
where w.shape = :shape \
and n.language = :lang \
and c.present is true
"""
def waffles = Waffle.executeQuery(query,[shape: 'square', lang: 'en',
max: 100, offset: 0])
Will get you first 100 waffles.
HQL based approach will be effective because restaurant, names and condiments will not be fetched eagerly which will be the case when Criteria is used as above.
Change lang
to 'fr' for French.