2011-01-17 6 views
4

Grailsには、「osによる統計の計算」や「ブラウザによる統計の計算」のような2つの非常によく似たメソッドがありますが、事実上両方を準備してからDBで同様のクエリを実行し、方法が異なる部分だけは、彼らは私の方法の真ん中に実行クエリです -Groovyで別のクロージャを追加できますか?

def summary = c.list { 
    eq('browser', Browser.get(1)) // OR eq('os', OS.get(1)) 
    between('date', dates.start, dates.end) 
} 

それをリファクタリングするための理想的な方法としてクロージャの最初の行に渡すことであろうと私に起こりましたメソッドパラメータ。 Like

doStats (Closure query) { 
    ... 
    def summary = c.list { 
     query 
     between('date', dates.start, dates.end) 
    } 
} 

私はこれを試しましたが、「クエリ」は無視されます。代わりにquery()を試しましたが、クエリ句が定義されている場所で実行されるため、これはどちらでも動作しません。私はパラメータとしてクロージャ全体を渡すことができると思うが、それは間違っているようだ - クエリーも将来もっと複雑になるかもしれない。

誰でも良いアイデアはありますか?

答えて

3

プレーンなGroovyクロージャとは異なるDSL基準を使用しています。

http://mrhaki.blogspot.com/2010/06/grails-goodness-refactoring-criteria.html

とプライベートメソッドにクエリを置く - あなたは、あなたがここで説明する方法を使用することができます求めているものを行うには

このため、よりエレガントな解決策はGrailsの中に名前付きクエリを使用することです - Grailsの基準で約

+0

ありがとう私は名前付きクエリのアイデアが好きです。皮肉なことに、それを使用して私はきれいなコードで終わることはありません。 doStats(Long domainId、Stringオブジェクト){ if(オブジェクト== 'ブラウザ'){ Stats。ブール値を使用することはできますが、基本的にはインライン条件クエリで直接渡されたLongとStringを使用して同じ結果が得られます。 – Fletch

2

わからない -

recentPublicationsWithBookInTitle { 
     // calls to other named queries… 
     recentPublications() 
     publicationsWithBookInTitle() 
    } 

例で

http://grails.org/doc/latest/ref/Domain%20Classes/namedQueries.html

ルックビルダーですが、他のビルダーと同じようにすることができます:

doStats (Closure query) { 
    def summary = c.list { 
     query(it) 
     between('date', dates.start, dates.end) 
    } 
} 

を介して、これを呼び出します。そうでない場合、あなたはおそらく最高の名前付きクエリlike tomas says

2

見ている

def f = { criteria -> 
    criteria.eq('browser', Browser.get(1)) 
} 
doStats(f) 

私は2個の別々のものから閉鎖を構成するためのleftShiftオペレータが有用であることが判明。あなたにできることは次のとおりです。

Closure a = { /*...*/ } 
Closure b = { /*...*/ } 
Closure c = a << b 

は、この例を見てみましょう:あなたはここで見ることができますどのような

def criteria = { 
    projection Projections.distinct(Projections.property('id')) 
    and { 
     eq 'owner.id', userDetails.id 

     if (filter.groupId) { 
      eq 'group.id', filter.groupId 
     } 
    } 
} 

List<Long> ids = Contact.createCriteria().list(criteria << { 
    maxResults filter.max 
    firstResult filter.offset 
}) 

Integer totalCount = Contact.createCriteria().count(criteria) 

は、私はアリカウントGORMオブジェクトをリストするためのcriteriaを作成していますということです。両方のケースのクリテリアはほぼ同じですが、リストの目的のために、コマンドオブジェクトからの制限とオフセットも含める必要があります。

+0

それは素晴らしい、ありがとう –

関連する問題