Grains paginate со списком из отношения 1: m - PullRequest
0 голосов
/ 26 октября 2010

В приведенном ниже случае авторский объект имеет существующий список «книг».Как выполнить разбиение на страницы в этом списке книг, если в контроллере уже есть объект 'author', и вы не хотите возвращаться в БД с другим запросом Book.findAll ("из Book as b, где b.author =: author", [автор: автор], [макс .: 10, смещение: 5])

class Author {
   String name
   static hasMany = [ books:book]
}
class Book {
   String title
   static belongsTo = [ author:Author ]
}

Ответы [ 2 ]

2 голосов
/ 28 октября 2010

давно не виделись!

Я бы, конечно, согласился с Робом здесь.

То, что вы увидите в журналах sql, - это несколько запросов для автора и книг в обоих случаях.Grails по умолчанию использует отложенную загрузку коллекций, поэтому в операторе

def author= Author.findByName(params.id)

Вы загрузили только автора, а не книги.

Добавление дополнительного оператора для загрузки книг в обычном разбивке на страницыпуть будет более эффективным и более обслуживаемым, так как он будет более чётким и более очевидным, что он делает.

Это стиль, который я обычно использую для получения данных такого типа.

def timeline = {  
    println "timeline[" + params+ "]"  
    if (params.id) {  
    def author= Author.findByName(params.id)   
    def books = Book.withCriteria {  
      eq('author', author)  
      firstResult(5)  
      maxResults(10)  
    }  
    def totalBooks = Book.createCriteria().count {  
      eq(author, author)  
    }  

    ...  
}

Кроме того (не уверен в этом), но оператор size () в коллекции книг вызовет запрос подсчета, но может также инициировать и другие запросы, поэтому он окупается, когда у вас есть такой большой набор данных, чтобы быть конкретными в том, чтовы получаете GORM.

(обновляется в соответствии с комментариями по счетам ниже)

0 голосов
/ 26 октября 2010

Я признаю, что я новичок Грааля - я считаю, что я, должно быть, что-то упустил.

Так что после многих недоразумений вот мое очень безобразное решение:

def timeline = {
println "timeline[" + params+ "]"
if (params.id) {
  def author= Author.findByName(params.id) 

  def allbooks = author?.books as List

  def max=params.max?:(allbooks.size()>2 ? 2: allbooks.size())
  def offset=params.offset?:(0)

  offset = offset as int
  max = max as int

  def start = offset*max > allbooks.size()-1 ? allbooks.size()-1 : offset*max
  def end = ((offset*max)+max-1) > allbooks.size()-1 ? allbooks.size() -1 : ((offset*max)+max-1)

  def books= allbooks.size() > 0?allbooks[(start)..(end)]:allbooks

  def bookCount = allbooks.size()

  println "max:" + params.max + ""
  println "books.size:" + books.size() + ", bookCount:" + bookCount

  [author, bookCount, books]
  }
...