GORM access list index of hasMany association

2019-05-11 08:04发布

My application has domain classes which have the same logical relation as photo albums and individual photographs. Using a List for the hasMany association should support backwards and forward movement within individual albums, without having to explicitly manage a position field or previous / next pointers.

For example:

class Album {
    static hasMany = [photos: Photo]
    List photos // Generates column `album_idx` in table for Photo.
    Integer size // Memoized.
}

class Photo {
    static belongsTo = [album: Album]
    static hasOne = [content: PhotoData] // PhotoData has byte[] field for data
}

class Controller {
    def prev() {
        def prevIdx = idx==0 ? album.size - 1 : idx -1 // etc.
    }
}

Can I access the value of the _idx without a native SQL query?

I've tried photo.album.photos.indexOf(photo), but indexOf returns -1 because the loading is apparently too lazy for indexOf, though in general I do want lazy loading. I blame lazy loading because in the debugger list items are randomly populated and I suspect those that are were simply cached previously. It's possible I'm misunderstanding GORM's behavior here.

In any event photo.album.photos.indexOf(photo) is uglier and (probably) slower than an immediate field access. Ideally I could define a mapping between the generated _idx column and a field in Photo, to allow access using photo.albumIdx.

1条回答
戒情不戒烟
2楼-- · 2019-05-11 08:49

Using indexColumn in combination with updateable and insertable mappings, you can have collection items (e.g. your Photos) index aware. For example:

class Album {
    static hasMany = [photos: Photo]
    List photos // Generates column `album_idx` in table for Photo.
    Integer size // Memoized.

    static mapping = {
      photos indexColumn: [name: "position", type: Integer]
    }
}

class Photo {
    Integer position

    static belongsTo = [album: Album]
    static hasOne = [content: PhotoData] // PhotoData has byte[] field for data

    static mapping = {
      position updateable: false, insertable: false
    }
}

photo.position will now give you this photo's index (NOTE: by default list order is 0 based)

查看更多
登录 后发表回答