pilagod / gorm-cursor-paginator

A paginator doing cursor-based pagination based on GORM
https://github.com/pilagod/gorm-cursor-paginator
MIT License
192 stars 44 forks source link

Allow Nested Struct Attribute For Rule Key #46

Closed khalilsarwari closed 2 years ago

khalilsarwari commented 2 years ago

I have the following situation:

stmt = s.DB.Preload("User").Joins("join posts on posts.user_id=users.id")

result, nextp, err := p.Paginate(stmt, &posts)

I would like to order by post.User.Registered, which is a boolean column on the users table.

If I put Key: "User.Registered", it gives the error that model fields should match rules or keys specified for paginator. I think this is because nested attributes are not checked for using reflection?

If I put Key: "User" instead, then it works for the first page, but then tries to cast the entire User object as a boolean thinking that it is the registered attribute, giving "cannot convert ... to bool" error.

Can support for nested attributes be added such that I can have Key: "User.Registered" when paginating posts joined with users ordered by registered property?

Thanks for your time! :)

pilagod commented 2 years ago

Hello @khalilsarwari, thanks for your question.

First of all, I think boolean key as paging key is not an ideal candidate, since boolean itself only has two values true and false. It would be better to add another key such as id to paging key along with the registered field to make it order properly.

And for the nested field part, maybe you could give our new feature CustomType a try in version v2.3.0. In order to use non-primitive field type, you have to add little new code:

  1. Make User struct implement the CustomType interface. You can see it in the paginator.Rule document as follows:
type CustomType interface {
    // GetCustomTypeValue returns the value corresponding to the meta attribute inside the custom type.
    GetCustomTypeValue(meta interface{}) (interface{}, error)
}

For a concrete custom type example, you could refer to the JSON type in the paginator test.

  1. Setup CustomType option in Rule while constructing paginator. The Meta field would be passed to User.GetCustomTypeValue as argument. Then you can return the right field value in that function according to the metadata.

    Please refer to this test for a real usage example.

Hope these information could help you to solve the problem. Thanks 😃

khalilsarwari commented 2 years ago

Hey @pilagod, thanks for the quick reply!

I combined the boolean key with the id into a string key so that the cursor would not just be a boolean. It is a bit of an odd use case but I just wanted top items false and bottom items true, and otherwise order was not important - I can see how that makes the pagination not work though.

I also followed what you said about using CustomType and it seems to be working now!

Thanks for your help! :)