Выборочное извлечение объекта из списка в объекте Grails Domain - PullRequest
2 голосов
/ 16 марта 2012

Я 2 месяца в разработке Grails и наткнулся на эту проблему, на которую я не могу найти ответ, воспользовавшись книгами, сайтом Grails и поиском по форуму. Я надеюсь, что кто-то может мне помочь.

У меня есть 2 класса домена - AccountPackage и AccountPackageFeatures. Идея состоит в том, что AccountPackage (например, Gold Account) может иметь много функций. Для представления этого в домене AccountPackage есть встроенный список AccountPackageFeatures. Вот два класса домена:

AccountPackage

class AccountPackage {
   String name      // eg. Gold Account
   boolean active   // eg. true - account is active

   List features = []
   static hasMany = [features:AccountPackageFeature]

   static constraints = {  }    
}

AccountPackageFeature

class AccountPackageFeature {

    String featureName      // eg.  "Number of posts allowed"
    String featureCategory  // eg.  "Job Posting"
    String value            // eg.  "10"

    static constraints = {  }

}

Данные уже сохранены в базе данных. В моем коде я получил конкретный экземпляр AccountPackage, и теперь я хочу найти определенную функцию этого AccountPackage. Я делаю это, чтобы получить список функций из экземпляра AccountPackage, а затем перебирать список, пока не найду интересующую меня функцию. Фрагмент кода ниже:

def desiredFeature = null
def desiredFeatureId = 10
AccountPackage pkg = AccountPackage.findByName("Gold Account")

def features = pkg.getFeatures()
for (feature in features) {
   if (feature.id == desiredFeatureId) {
       desiredFeature = feature 
   }
}

Я знаю, что это довольно неэффективно ... но какое право делать это в Grails ??

Предоставляет ли Grails / GORM какие-либо встроенные функции, чтобы избавить меня от выполнения пользовательского запроса? В качестве альтернативы я должен, например, добавить пользовательский метод в мой объект домена AccountPackage, который называется что-то вроде getFeatureWithId, который принимает идентификатор, а затем выполняет пользовательский запрос для возврата требуемой функции?

Буду очень признателен за любой совет относительно наилучшей практики / правильного способа сделать это.

Ответы [ 3 ]

3 голосов
/ 16 марта 2012

попробуйте

    AccountPackage.findByNameAndFeature("Gold Account",AccountPackageFeature.findById(desiredFeatureId))

или

 AccountPackageFeature.findByIdAndAccountPackage(desiredFeatureId,AccountPackage.findByName("Gold Account"))
2 голосов
/ 19 марта 2012

Почему вы сказали бы, что ваш поисковый фрагмент неэффективен? Его сложность линейна, поэтому на практике его эффективность зависит от количества функций, которые может иметь пакет учетной записи. Если эта сумма составляет порядка десятых долей, вам не стоит ничего оптимизировать.

Как правило, «ранняя оптимизация - корень всего зла». Я предлагаю вам внедрить ваше решение и протестировать его производительность в реальных сценариях использования, чтобы увидеть, не наносит ли его неэффективность производительность вашего приложения.

Теперь о вашем фрагменте, вы можете использовать некоторые интересные возможности языка Groovy, я бы переписал его так:

def getFeatureById(desiredFeatureId) {
    def pkg = AccountPackage.findByName("Gold Account")
    pkg.features.find { feature -> feature.id == desiredFeatureId }
}

Вы можете прочитать о Коллекциях и Закрытиях на сайте Groovy

0 голосов
/ 16 марта 2012

Вы можете использовать динамические искатели на своем втором домене вместо цикла

 AccountPackage pkg = AccountPackage.findByName("Gold Account")
 def desiredFeature = pkg ? AccountPackageFeature.findByAccountPackage(pkg) : []

Посмотрите на нажмите здесь и найдите Запрос ассоциаций для получения дополнительной информации

...