Skip to content

Instantly share code, notes, and snippets.

@fnordfish
Last active May 3, 2016 13:52
Show Gist options
  • Select an option

  • Save fnordfish/4f5cbd11a4e76ed56914679eebc29510 to your computer and use it in GitHub Desktop.

Select an option

Save fnordfish/4f5cbd11a4e76ed56914679eebc29510 to your computer and use it in GitHub Desktop.
A Yaks policy to work on Sequel::Dataset (without converting them to Array first)
module YaksSequel
class CollectionMapper < Yaks::CollectionMapper
attr_reader :collection_dataset
def call(collection, *args)
return super unless collection.is_a?(Sequel::Dataset)
@collection_dataset = collection
if collection.opts[:eager_graph]
super(collection.all, *args)
else
super
end
end
end
end
module YaksSequel
# Pagination Mapper for Sequel's pagination extension.
#
# This mapper works on a `Sequel::Dataset::Pagination`. It does not paginate
# by itself.
#
# It will create links using the `page[number]` and `page[size]` request query
# parameters.
class PaginatedCollectionMapper < YaksSequel::CollectionMapper
include Memoizable
PAGE_NUMBER_PARAM = "page%5Bnumber%5D"
PAGE_SIZE_PARAM = "page%5Bsize%5D"
link :first, -> { link_to_page(1) }
link :prev, -> { link_to_page(collection_dataset.prev_page) }
link :next, -> { link_to_page(collection_dataset.next_page) }
link :last, -> { link_to_page(collection_dataset.page_count) }
def params
Rack::Request.new(env).params
end
memoize :params
def requested_page_size
params.dig("page", "size").to_i.nonzero?
end
memoize :requested_page_size
def paged_link_template
URITemplate.new("#{env['PATH_INFO']}{?#{PAGE_SIZE_PARAM},#{PAGE_NUMBER_PARAM}}")
end
memoize :paged_link_template
def link_to_page(page_num)
paged_link_template.expand(PAGE_NUMBER_PARAM => page_num, PAGE_SIZE_PARAM => requested_page_size) if page_num
end
end
end
module YaksSequel
class Policy < Yaks::DefaultPolicy
def derive_mapper_from_object(model)
return super unless model.is_a?(Sequel::Dataset)
derive_mapper_from_collection(model)
end
def derive_type_from_collection(collection)
return super unless collection.is_a?(Sequel::Dataset)
underscore(collection.model.name.split("::").last.sub(/Mapper$/, ""))
end
def derive_mapper_from_collection(collection)
return super unless collection.is_a?(Sequel::Dataset)
model_name = collection.model.name.split("::").last
if collection.is_a?(Sequel::Dataset::Pagination)
name = "#{model_name}PaginatedCollectionMapper"
begin
return @options[:namespace].const_get(name)
rescue NameError
end
PaginatedCollectionMapper
else
name = "#{model_name}CollectionMapper"
begin
return @options[:namespace].const_get(name)
rescue NameError
end
CollectionMapper
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment