-
Notifications
You must be signed in to change notification settings - Fork 412
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
430 additions
and
24 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,222 @@ | ||
# frozen_string_literal: true | ||
|
||
# Starting point to reproduce keyset related pagy issues | ||
|
||
# DEV USAGE | ||
# pagy clone rails | ||
# pagy ./keyset.ru | ||
|
||
# URL | ||
# http://0.0.0.0:8000 | ||
|
||
# HELP | ||
# pagy -h | ||
|
||
# DOC | ||
# https://ddnexus.github.io/pagy/playground/#5-keyset-app | ||
|
||
VERSION = '8.6.2' | ||
|
||
# Gemfile | ||
require 'bundler/inline' | ||
require 'bundler' | ||
Bundler.configure | ||
gemfile(ENV['PAGY_INSTALL_BUNDLE'] == 'true') do | ||
source 'https://rubygems.org' | ||
gem 'oj' | ||
gem 'puma' | ||
gem 'rails' | ||
# activerecord/sqlite3_adapter.rb probably useless) constraint !!! | ||
# https://github.com/rails/rails/blame/v7.1.3.4/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb#L14 | ||
gem 'sqlite3', '~> 1.4.0' | ||
end | ||
|
||
# require 'rails/all' # too much stuff | ||
require 'action_controller/railtie' | ||
require 'active_record' | ||
|
||
OUTPUT = Rails.env.showcase? ? IO::NULL : $stdout | ||
|
||
# Rails config | ||
class PagyKeyset < Rails::Application # :nodoc: | ||
config.root = __dir__ | ||
config.session_store :cookie_store, key: 'cookie_store_key' | ||
Rails.application.credentials.secret_key_base = 'absolute_secret' | ||
|
||
config.logger = Logger.new(OUTPUT) | ||
Rails.logger = config.logger | ||
|
||
routes.draw do | ||
root to: 'comments#index' | ||
get '/javascripts/:file', to: 'pagy#javascripts', file: /.*/ | ||
end | ||
end | ||
|
||
# AR config | ||
dir = Rails.env.development? ? '.' : Dir.pwd # app dir in dev or pwd otherwise | ||
unless File.writable?(dir) | ||
warn "ERROR: directory #{dir.inspect} is not writable (the pagy-rails-app needs to create DB files)" | ||
exit 1 | ||
end | ||
|
||
# Pagy initializer | ||
require 'pagy/extras/pagy' | ||
require 'pagy/extras/items' | ||
require 'pagy/extras/overflow' | ||
Pagy::DEFAULT[:items] = 10 | ||
Pagy::DEFAULT[:overflow] = :empty_page | ||
Pagy::DEFAULT.freeze | ||
|
||
# Activerecord initializer | ||
ActiveRecord::Base.logger = Logger.new(OUTPUT) | ||
ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: "#{dir}/tmp/pagy-keyset.sqlite3") | ||
ActiveRecord::Schema.define do | ||
create_table :pets, force: true do |t| | ||
t.string :name | ||
t.string :animal | ||
t.datetime :birth | ||
end | ||
end | ||
|
||
# Models | ||
class Pet < ActiveRecord::Base # :nodoc: | ||
end # :nodoc: | ||
|
||
# Helpers | ||
module CommentsHelper | ||
include Pagy::Frontend | ||
end | ||
|
||
# Controllers | ||
class CommentsController < ActionController::Base # :nodoc: | ||
include Rails.application.routes.url_helpers | ||
include Pagy::Backend | ||
|
||
def index | ||
# @pagy, @pets = pagy_keyset(Pets.all, | ||
# reorder: %i[animal name birth id], | ||
# direction: :asc, | ||
# items: 5) | ||
@pets = Pet.all | ||
render inline: TEMPLATE | ||
end | ||
end | ||
|
||
TEMPLATE = <<~ERB | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<html> | ||
<head> | ||
<title>Pagy Keyset App</title> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||
<style type="text/css"> | ||
@media screen { html, body { | ||
font-size: 1rem; | ||
line-height: 1.2s; | ||
padding: 0; | ||
margin: 0; | ||
} } | ||
body { | ||
background: white !important; | ||
margin: 0 !important; | ||
font-family: sans-serif !important; | ||
} | ||
.content { | ||
padding: 1rem 1.5rem 2rem !important; | ||
} | ||
<%== Pagy.root.join('stylesheets', 'pagy.css').read %> | ||
</style> | ||
</head> | ||
<body> | ||
<div class="content"> | ||
<h1>Pagy Keyset App</h1> | ||
<p>Self-contained, standalone Rails app usable to easily reproduce any keyset related pagy issue.</p> | ||
<p>Please, report the following versions in any new issue.</p> | ||
<h2>Versions</h2> | ||
<ul> | ||
<li>Ruby: <%== RUBY_VERSION %></li> | ||
<li>Rack: <%== Rack::RELEASE %></li> | ||
<li>Rails: <%== Rails.version %></li> | ||
<li>Pagy: <%== Pagy::VERSION %></li> | ||
</ul> | ||
<h3>Collection</h3> | ||
<div id="records" class="collection"> | ||
<% @pets.each do |pet| %> | ||
<p style="margin: 0;"><%= pet.name %></p> | ||
<% end %> | ||
</div> | ||
<hr> | ||
<%# pagy_next_a(@pagy) %> | ||
</div> | ||
</body> | ||
</html> | ||
ERB | ||
|
||
PETS = <<~PETS | ||
Kiki | dog | 2018-3-10 | ||
Losi | cat | 2019-5-15 | ||
Dodo | dog | 2020-6-25 | ||
Wiki | brid | 2018-3-12 | ||
Baby | rabbit | 2020-1-13 | ||
Neki | horse | 2021-7-20 | ||
Tino | donkey | 2019-6-18 | ||
Plot | cat | 2022-9-21 | ||
Riki | snake | 2018-9-14 | ||
Lucky | horse | 2018-10-26 | ||
Coco | pig | 2020-8-29 | ||
Momo | chicken | 2023-8-25 | ||
Lili | cat | 2021-7-22 | ||
Beli | pig | 2020-7-26 | ||
Milla | chicken | 2022-8-19 | ||
Vyvy | panda | 2018-5-16 | ||
Susi | cow | 2024-1-25 | ||
Ella | cat | 2022-2-7 | ||
Rocky | dog | 2019-9-19 | ||
Juni | rabbit | 2020-8-24 | ||
Sini | bird | 2021-3-17 | ||
Hasky | dog | 2021-7-28 | ||
Luna | horse | 2023-5-14 | ||
Gigi | pig | 2022-5-19 | ||
Fema | panda | 2020-2-20 | ||
Nino | donkey | 2019-6-17 | ||
Dani | cat | 2022-2-9 | ||
Popi | dog | 2020-9-26 | ||
Anne | pig | 2022-6-18 | ||
Mina | cow | 2021-4-21 | ||
Willy | rabbit | 2023-5-18 | ||
Toni | donkey | 2018-6-22 | ||
Sooly | horse | 2019-9-28 | ||
Taky | panda | 2019-3-18 | ||
Roby | cat | 2023-4-14 | ||
Ano | horse | 2022-8-18 | ||
Eno | pig | 2020-5-16 | ||
Boly | bird | 2020-3-29 | ||
Sky | cat | 2023-7-19 | ||
Lili | dog | 2020-1-28 | ||
Fami | snake | 2023-4-27 | ||
Lopi | pig | 2019-6-19 | ||
Hopo | snake | 2022-3-13 | ||
Denis | dog | 2022-6-19 | ||
Maca | cat | 2024-2-11 | ||
Cako | panda | 2022-8-15 | ||
Jeme | horse | 2019-8-8 | ||
Sary | donkey | 2023-4-29 | ||
Vivo | chicken | 2023-5-14 | ||
Nomo | panda | 2023-5-27 | ||
PETS | ||
|
||
# DB seed | ||
pets = [] | ||
PETS.each_line(chomp: true) do |pet| | ||
name, animal, birth = pet.split('|').map(&:strip) | ||
pets << { name:, animal:, birth: } | ||
puts pets.to_json | ||
end | ||
Pet.insert_all(pets) | ||
|
||
run PagyKeyset |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
# frozen_string_literal: true | ||
|
||
class Pagy # :nodoc: | ||
# Cheap Base64 specialized methods to avoid dependencies | ||
module B64 | ||
module_function | ||
|
||
def encode(bin) | ||
[bin].pack('m0') | ||
end | ||
|
||
def decode(str) | ||
str.unpack1('m0') | ||
end | ||
|
||
def urlsafe_encode(bin) | ||
str = encode(bin) | ||
str.chomp!('==') or str.chomp!('=') | ||
str.tr!('+/', '-_') | ||
str | ||
end | ||
|
||
def urlsafe_decode(str) | ||
if !str.end_with?('=') && str.length % 4 != 0 | ||
str = str.ljust((str.length + 3) & ~3, '=') | ||
str.tr!('-_', '+/') | ||
else | ||
str = str.tr('-_', '+/') | ||
end | ||
decode(str) | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
# See the Pagy documentation: https://ddnexus.github.io/pagy/docs/extras/keyset | ||
# frozen_string_literal: true | ||
|
||
require_relative '../keyset' | ||
require 'base64' | ||
|
||
class Pagy # :nodoc: | ||
# Add keyset pagination | ||
module KeysetExtra | ||
# Return Pagy::Keyset object and paginated records | ||
def pagy_keyset(scope, vars = {}) | ||
pagy = Keyset.new(scope:, **pagy_keyset_get_vars(scope, vars)) | ||
[pagy, pagy_keyset_get_items(scope, pagy)] | ||
end | ||
|
||
# Sub-method called only by #pagy_keyset: here for easy customization of variables by overriding | ||
def pagy_keyset_get_vars(scope, vars) | ||
pagy_set_items_from_params(vars) if defined?(ItemsExtra) | ||
vars[:page] ||= pagy_get_page(vars) | ||
vars[:order] ||= pagy_get_order(scope) | ||
end | ||
|
||
# Get the page integer from the params | ||
# Overridable by the jsonapi extra | ||
def pagy_get_page(vars) | ||
params[vars[:page_param] || DEFAULT[:page_param]] | ||
end | ||
|
||
# Extract the order from the scope | ||
def pagy_get_order(scope) | ||
scope.order_values.each_with_object([]) do |node, order| | ||
order << { node.value.name.to_sym => node.direction } | ||
end | ||
end | ||
|
||
# Sub-method called only by #pagy_keyset: here for easy customization of record-extraction by overriding | ||
def pagy_keyset_get_items(scope, pagy) | ||
scope.where(pagy.where).limit(pagy.items) | ||
end | ||
end | ||
Backend.prepend KeysetExtra | ||
end |
Oops, something went wrong.