paginated_collection.rb 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. # frozen_string_literal: true
  2. module ShopifyAPI
  3. class PaginatedCollection < ActiveResource::Collection
  4. module CollectionPagination
  5. def initialize(args)
  6. @next_url = pagination_link_headers.next_link&.url&.to_s
  7. @previous_url = pagination_link_headers.previous_link&.url&.to_s
  8. super(args)
  9. end
  10. def next_page?
  11. ensure_available
  12. @next_url.present?
  13. end
  14. def previous_page?
  15. ensure_available
  16. @previous_url.present?
  17. end
  18. def fetch_next_page
  19. fetch_page(@next_url)
  20. end
  21. def fetch_previous_page
  22. fetch_page(@previous_url)
  23. end
  24. def next_page_info
  25. extract_page_info(@next_url)
  26. end
  27. def previous_page_info
  28. extract_page_info(@previous_url)
  29. end
  30. private
  31. AVAILABLE_IN_VERSION = ShopifyAPI::ApiVersion.find_version('2019-10')
  32. AVAILABLE_IN_VERSION_EARLY = ShopifyAPI::ApiVersion.find_version('2019-07')
  33. def fetch_page(url)
  34. ensure_available
  35. return [] unless url.present?
  36. resource_class.all(from: url)
  37. end
  38. def pagination_link_headers
  39. @pagination_link_headers ||= ShopifyAPI::PaginationLinkHeaders.new(
  40. ShopifyAPI::Base.connection.response["Link"]
  41. )
  42. end
  43. def ensure_available
  44. return if ShopifyAPI::Base.api_version >= AVAILABLE_IN_VERSION
  45. return if ShopifyAPI::Base.api_version >= AVAILABLE_IN_VERSION_EARLY && resource_class.early_july_pagination?
  46. raise NotImplementedError
  47. end
  48. def extract_page_info(url)
  49. CGI.escape(Rack::Utils.parse_query(URI(url).query)['page_info']) if url.present?
  50. end
  51. end
  52. include CollectionPagination
  53. end
  54. end