2012-06-29 36 views
1

在我們的應用程序中,我們有一個可以有遊戲和練習計劃的玩家,因此我們設計了抽象類Plan和兩個派生類GamePlan和PracticePlan。在數據庫中,派生類用'class'屬性保存到一個表中。Grails與抽象類的一對多

當我們在特定的玩家上使用getPlans()時,我們得到了所有的計劃,但我們想知道如何獲得遊戲或實踐計劃。類似於player.getPracticePlans()或Player.PracticePlans(player_id)。以下是我們的課程。

class Player { 

    String name 
    static hasMany = [ plans : Plan] 
} 

abstract class Plan { 
} 

class PracticePlan extends Plan{ 
} 

class GamePlan extends Plan{ 
} 

注意:我們嘗試使用類似:

def query = Player.where { 
    plans { class == "GamePlan" } 
} 

但類是保留關鍵字,它不編譯。

+0

你計劃上課'belongsTo'玩家嗎? –

+0

不,一個計劃可以在許多用戶之間共享。 – MBozic

+0

個人而言,我只是做靜態hasMany = [gamePlans:GamePlan,practicePlans:PracticePlan]。這不會簡化事情嗎? – Gregg

回答

1

我相信你能做到這一點加載一人所有計劃,然後過濾掉不想要的:

def gamePlansForPlayer = Player.get(id).plans.findAll { plan -> 
    plan.instanceOf(GamePlan) 
} 

沒有測試它雖然:-(

+0

它的工作原理,謝謝!你能回答我嗎,hibernate是否加載GamePlan和PracticePlan公共表中的所有Plan實例,並在應用程序級別對它們進行過濾,或者在查詢中進行過濾?如果它加載了所有內容,最好是說Player分別具有PracticePlans和GamePlans? – MBozic

+0

這會將一個'Player'的所有計劃加載到內存中,然後將該列表過濾到'GamePlan'實例。我會等待這個問題,因爲別人可能知道一種方法來編寫HQL或一個標準來做到這一點在數據庫級別,並避免這種開銷... –

0

你應該能夠得到。與getClass()類看到這個答案:Groovy/grails how to determine a data type?

你也可以使用一個Criteria,這將使列到報價,所以它不反對保留字問題跑起來:

def plans = Player.withCriteria { 
    plans { 
     eq('class', "com.name.space.GamePlan") 
    } 
} 

(請注意,我使用命名空間指定了類名,因爲這是它存儲在我的經驗中的方式。 。YMMV)

如果這個工程,你想讓它更一般的,你可以把它變成一個named query並提供類作爲參數:

def namedQueries = { 
    plansByClass = { clazz -> 
     plans { 
      eq('class', clazz) 
     } 
    } 
} 

然後你把這個像一個靜態方法:

def plans = Player.plansByClass('GamePlan') 

請注意,儘管我在我的應用程序中使用了Criteria,但未對這些特定示例進行測試。

+1

Ie Cristo我剛剛意識到這是從2012年_ _ < –