Um paginador baseado em escopo e motor, limpo, poderoso, personalizável e sofisticado para estruturas de aplicativos da web modernos e ORMs
Não poluia globalmente Array
, Hash
, Object
ou AR::Base
.
Basta agrupar a jóia, então seus modelos estão prontos para serem paginados. Nenhuma configuração necessária. Não precisa definir nada em seus modelos ou ajudantes.
Tudo é método encadeado com menos "hashherite". Você sabe, essa é a maneira moderna do Rails. Nenhuma classe de coleta especial ou qualquer coisa para os valores paginados, em vez de usar uma instância geral AR::Relation
. Portanto, é claro que você pode encadear outras condições antes ou depois do escopo do paginador.
Como todo o ajudante de paginação é basicamente apenas uma coleção de links e não ligações, Kaminari renderiza cada um deles através de seu próprio modelo parcial dentro do motor. Portanto, você pode modificar facilmente seu comportamento, estilo ou qualquer outra coisa, substituindo modelos parciais.
O Kaminari suporta vários ORMs (ActiveRecord, Datamapper, Mongoid, MongoMapper), várias estruturas da Web (Rails, Sinatra, Grape) e vários motores de modelo (ERB, Haml, Slim).
O ajudante de paginação produz a tag HTML5 <nav>
por padrão. Além disso, o ajudante suporta o Ajax discreto do Rails.
Ruby 2.1, 2.2, 2,3, 2,4, 2,5, 2,6, 2,7, 3.0, 3.1, 3.2, 3.3, 3,3
Rails 4.1, 4.2, 5.0, 5.1, 5.2, 6.0, 6.1, 7.0, 7.1, 7.2, 8.0, 8.0
Sinatra 1.4, 2.0
Haml 3+
Mongoid 3+
MongoMapper 0,9+
Datamapper 1.1.0+
Para instalar o Kaminari na pilha de trilhos padrão, basta colocar essa linha no seu GemFile:
gem 'kaminari'
Em seguida, pacote:
% bundle
Se você estiver construindo um aplicativo não-trilhos ou não-contrato de ação e deseja o recurso de paginação, dê uma olhada em outra seção de suporte à estrutura/biblioteca.
page
Para buscar a 7ª página dos usuários (o padrão per_page
é 25)
User . page ( 7 )
Nota: A paginação é iniciada na página 1, não na página 0 (página (0) retornará os mesmos resultados que a página (1)).
Kaminari não adiciona um order
às consultas. Para evitar surpresas, você geralmente deve incluir uma ordem em consultas paginadas. Por exemplo:
User . order ( :name ) . page ( 7 )
Você pode obter números de página ou condições de página usando os métodos abaixo.
User . count #=> 1000
User . page ( 1 ) . limit_value #=> 20
User . page ( 1 ) . total_pages #=> 50
User . page ( 1 ) . current_page #=> 1
User . page ( 1 ) . next_page #=> 2
User . page ( 2 ) . prev_page #=> 1
User . page ( 1 ) . first_page? #=> true
User . page ( 50 ) . last_page? #=> true
User . page ( 100 ) . out_of_range? #=> true
per
Para mostrar muito mais usuários por cada página (altere o valor per
valor)
User . order ( :name ) . page ( 7 ) . per ( 50 )
Observe que o escopo per
não está diretamente definido nos modelos, mas é apenas um método definido no escopo da página. Isso é absolutamente razoável, porque você nunca usará per
fato sem especificar o número page
.
Lembre -se de que, per
o limite, utiliza internamente limit
e, portanto, substituirá qualquer limit
definido anteriormente. E se você deseja obter o tamanho para todos os registros de solicitação, pode usar o método total_count
:
User . count #=> 1000
a = User . limit ( 5 ) ; a . count #=> 5
a . page ( 1 ) . per ( 20 ) . size #=> 20
a . page ( 1 ) . per ( 20 ) . total_count #=> 1000
padding
Ocasionalmente, você precisa preencher vários registros que não são um múltiplo do tamanho da página.
User . order ( :name ) . page ( 7 ) . per ( 50 ) . padding ( 3 )
Observe que o escopo padding
também não é definido diretamente nos modelos.
except(:limit, :offset)
per
por algum page
users = User . order ( :name ) . page ( 7 ) . per ( 50 )
unpaged_users = users . except ( :limit , :offset ) # unpaged_users will not use the kaminari scopes
Você pode configurar os seguintes valores padrão, substituindo esses valores usando o método Kaminari.configure
.
default_per_page # 25 by default
max_per_page # nil by default
max_pages # nil by default
window # 4 by default
outer_window # 0 by default
left # 0 by default
right # 0 by default
page_method_name # :page by default
param_name # :page by default
params_on_first_page # false by default
Há um gerador útil que gera o arquivo de configuração padrão no diretório Config/Initializers. Execute o seguinte comando gerador e edite o arquivo gerado.
% rails g kaminari:config
page_method_name
Você pode alterar a page
de nome do método para bonzo
ou plant
ou o que quiser, a fim de jogar bem com o método ou associação ou escopo page
existente ou qualquer outro plug -in que defina o método page
em seus modelos.
paginates_per
Você pode especificar o valor per_page
padrão por cada modelo usando o seguinte DSL declarativo.
class User < ActiveRecord :: Base
paginates_per 50
end
max_paginates_per
Você pode especificar o valor max per_page
por cada modelo usando o seguinte DSL declarativo. Se a variável especificada via per
for mais do que essa variável, max_paginates_per
será usado em vez disso. O valor padrão é nulo, o que significa que você não está impondo nenhum valor máximo per_page
.
class User < ActiveRecord :: Base
max_paginates_per 100
end
max_pages
Você pode especificar o valor max_pages
por cada modelo usando o seguinte DSL declarativo. Esse valor restringe o número total de páginas que podem ser retornadas. Útil para definir limites para grandes coleções.
class User < ActiveRecord :: Base
max_pages 100
end
Se você estiver usando a gema ransack_memory
e tiver problemas de navegar para a configuração anterior ou a primeira página, defina a configuração params_on_first_page
como true
.
params[:page]
Normalmente, seu código do controlador ficará assim:
@users = User . order ( :name ) . page params [ :page ]
Basta ligar para o ajudante paginate
:
<%= paginate @users %>
Isso renderizará vários links de <nav>
?page=N
paginate
<%= paginate @users %>
Isso produziria vários links de paginação, como « First ‹ Prev ... 2 3 4 5 6 7 8 9 10 ... Next › Last »
.
<%= paginate @users, window: 2 %>
Isso geraria algo como ... 5 6 7 8 9 ...
quando 7 é a página atual.
<%= paginate @users, outer_window: 3 %>
Isso produziria algo como 1 2 3 ...(snip)... 18 19 20
tendo 20 páginas no total.
<%= paginate @users, left: 1, right: 3 %>
Isso produziria algo como 1 ...(snip)... 18 19 20
, tendo 20 páginas no total.
:param_name
) para os links <%= paginate @users, param_name: :pagina %>
Isso modificaria o nome do parâmetro de consulta em cada links.
:params
) para os links <%= paginate @users, params: {controller: 'foo', action: 'bar', format: :turbo_stream} %>
Isso modificaria url_option
de cada link. :controller
e :action
pode ser as chaves em comum.
<%= paginate @users, remote: true %>
Isso adicionaria data-remote="true"
a todos os links internos.
<%= paginate @users, views_prefix: 'templates' %>
Isso procuraria parciais em app/views/templates/kaminari
. Essa opção facilita a realização de coisas como modelos/temas de paginação de teste A/B, usando modelos novos/antigos ao mesmo tempo, além de uma melhor integração com outras gemas, como células.
link_to_next_page
e link_to_previous_page
(aliases para link_to_prev_page
) métodos auxiliares <%= link_to_next_page @items, 'Next Page' %>
Isso simplesmente renderiza um link para a próxima página. Isso seria útil para criar um recurso de paginação semelhante ao Twitter.
Os métodos auxiliares suportam uma opção params
para especificar ainda mais o link. Se format
precisar ser definido, inclua -o no hash params
.
<%= link_to_next_page @items, 'Next Page', params: {controller: 'foo', action: 'bar', format: :turbo_stream} %>
page_entries_info
Helper <%= page_entries_info @posts %>
Isso torna uma mensagem útil com números de entradas exibidas versus totais.
Por padrão, a mensagem usará o nome da classe humanizado de objetos na coleção: por exemplo, "tipos de projeto" para modelos ProjectType. O espaço para nome será cortado e apenas o sobrenome será usado. Substitua isso com o parâmetro :entry_name
:
<%= page_entries_info @posts, entry_name: 'item' %>
#= > Displaying items 6 - 10 of 26 in total
rel_next_prev_link_tags
<%= rel_next_prev_link_tags @users %>
Isso renderiza as tags de link REL Next e Prev para a cabeça.
path_to_next_page
Helper <%= path_to_next_page @users %>
Isso retorna o caminho relativo do servidor para a próxima página.
path_to_prev_page
<%= path_to_prev_page @users %>
Isso retorna o caminho relativo do servidor para a página anterior.
Os rótulos padrão para 'First', 'Last', 'Anterior', '...' e 'Next' são armazenados na iaml i18n dentro do motor e renderizados na API I18N. Você pode alternar o valor do rótulo por i18n.locale para sua aplicação internacionalizada. As chaves e os valores padrão são os seguintes. Você pode substituí -los adicionando a um arquivo YAML no seu diretório Rails.root/config/locales
.
en :
views :
pagination :
first : " « First "
last : " Last » "
previous : " ‹ Prev "
next : " Next › "
truncate : " … "
helpers :
page_entries_info :
one_page :
display_entries :
zero : " No %{entry_name} found "
one : " Displaying <b>1</b> %{entry_name} "
other : " Displaying <b>all %{count}</b> %{entry_name} "
more_pages :
display_entries : " Displaying %{entry_name} <b>%{first}–%{last}</b> of <b>%{total}</b> in total "
Se você usar localização não inglesa, consulte as regras i18n para alterar o bloco one_page:display_entries
.
Kaminari inclui um gerador de modelo útil.
Execute o gerador primeiro,
% rails g kaminari:views default
Em seguida, edite os parciais no app/views/kaminari/
diretório.
Você pode usar a gema html2haml ou a gema html2slim para converter modelos de erb. A GEM Kaminari captará automaticamente modelos Haml/Slim se você os colocar em app/views/kaminari/
.
Caso você precise de modelos diferentes para o seu paginador (por exemplo, público e administrador), você pode passar --views-prefix directory
como este:
% rails g kaminari:views default --views-prefix admin
Isso gerará parciais no app/views/admin/kaminari/
Diretório.
O gerador tem a capacidade de buscar vários temas de modelo de amostra do repositório externo (https://github.com/amatsuda/kaminari_themes), além do "padrão", o que o ajudará a criar um paginador bonito.
% rails g kaminari:views THEME
Para ver a lista completa dos temas disponíveis, dê uma olhada no repositório de temas ou apenas acerte o gerador sem especificar o argumento THEME
.
% rails g kaminari:views
Para utilizar vários temas de um único aplicativo, crie um diretório dentro do aplicativo/Views/Kaminari/e mova seus arquivos de modelo personalizado para esse diretório.
% rails g kaminari:views default (skip if you have existing kaminari views)
% cd app/views/kaminari
% mkdir my_custom_theme
% cp _ * .html. * my_custom_theme/
Em seguida, faça referência a esse diretório ao chamar o método paginate
:
<%= paginate @users, theme: 'my_custom_theme' %>
Personalize!
NOTA: Se o tema não estiver presente ou nenhum for especificado, o Kaminari padrão de volta às visualizações incluídas no GEM.
Geralmente, o paginador precisa saber o número total de registros para exibir os links, mas às vezes não precisamos do número total de registros e apenas precisamos dos links "página anterior" e "próxima página". Para esse caso de uso, o Kaminari fornece o modo without_count
que cria uma coleção paginável sem contar o número de todos os registros. Isso pode ser útil quando você está lidando com um conjunto de dados muito grande, porque contar com uma grande mesa tende a ficar lento no RDBMS.
Basta adicionar .without_count
ao seu objeto paginado:
User . page ( 3 ) . without_count
No seu arquivo de visualização, você pode usar apenas ajudantes simples, como o seguinte, em vez do ajudante paginate
completo:
<%= link_to_prev_page @users, 'Previous Page' %>
<%= link_to_next_page @users, 'Next Page' %>
Kaminari fornece uma classe de wrapper de matriz que adapta um objeto de matriz genérico ao ajudante de visualização paginate
. No entanto, o ajudante paginate
não lida automaticamente no seu objeto de matriz (isso é intencional e por design). Kaminari::paginate_array
Método converte seu objeto de matriz em uma matriz paginatável que aceita o método page
.
@paginatable_array = Kaminari . paginate_array ( my_array_object ) . page ( params [ :page ] ) . per ( 10 )
Você pode especificar o valor total_count
através do hash de opções. Isso seria útil ao lidar com um objeto de matriz que possui um valor count
diferente da count
real, como o resultado da pesquisa do RSOLR ou quando você precisa gerar uma paginação personalizada. Por exemplo:
@paginatable_array = Kaminari . paginate_array ( [ ] , total_count : 145 ) . page ( params [ :page ] ) . per ( 10 )
Ou, no caso de usar uma API externa para obter a página dos dados:
page_size = 10
one_page = get_page_of_data params [ :page ] , page_size
@paginatable_array = Kaminari . paginate_array ( one_page . data , total_count : one_page . total_count ) . page ( params [ :page ] ) . per ( page_size )
Devido ao parâmetro page
e ao roteamento dos trilhos, você pode gerar facilmente URLs de SEO e fácil de usar. Para qualquer recurso que você queira pagar, basta adicionar o seguinte às suas routes.rb
:
resources :my_resources do
get 'page/:page' , action : :index , on : :collection
end
Se você estiver usando o Rails 4 ou posterior, poderá simplificar as definições de rota usando concern
:
concern :paginatable do
get '(page/:page)' , action : :index , on : :collection , as : ''
end
resources :my_resources , concerns : :paginatable
Isso criará URLs como /my_resources/page/33
em vez de /my_resources?page=33
. Agora é um URL amigável, mas também tem outros benefícios adicionais ...
Como o parâmetro page
agora é um segmento de URL, podemos alavancar em cache de páginas de trilhos!
NOTA: Neste exemplo, apontei a rota para a minha :index
. Você pode ter definido uma ação de paginação personalizada em seu controlador - você deve apontar action: :your_custom_action
.
Tecnicamente, o Kaminari Gem consiste em 3 componentes individuais:
kaminari-core: the core pagination logic
kaminari-activerecord: Active Record adapter
kaminari-actionview: Action View adapter
Portanto, gem 'kaminari'
é equivalente às 2 linhas a seguir (o núcleo Kaminari é referenciado dos adaptadores):
gem 'kaminari-activerecord'
gem 'kaminari-actionview'
Se você deseja usar outros ORMs suportados em vez do ActiveRecord, por exemplo, mongóides, agrupe seu adaptador em vez do Kaminari-ActiveRecord.
gem 'kaminari-mongoid'
gem 'kaminari-actionview'
Kaminari atualmente fornece adaptadores para o seguinte ORMS:
Se você deseja usar outras estruturas da Web em vez de Visualização de Rails + Action, por exemplo, Sinatra, agrupe seu adaptador em vez do Kaminar-ActionView.
gem 'kaminari-activerecord'
gem 'kaminari-sinatra'
Kaminari atualmente fornece adaptadores para as seguintes estruturas da web:
Confira as receitas Kaminari no Wiki do Github para obter dicas e técnicas mais avançadas. https://github.com/kaminari/kaminari/wiki/kaminari-recipes
Sinta -se à vontade para me enviar uma mensagem no github (amatsuda) ou no Twitter (@a_matsuda) ☇☇☇ :)
Garfo, conserte e envie uma solicitação de tração.
Para executar a suíte de teste localmente contra todas as estruturas suportadas:
% bundle install
% rake test:all
Para direcionar a suíte de teste contra uma estrutura:
% rake test:active_record_50
Você pode encontrar uma lista de tarefas de teste suportadas executando rake -T
. Você também pode achar útil executar um teste específico para uma estrutura específica. Para fazer isso, você precisará primeiro garantir que você tenha incluído tudo para essa configuração, então você pode executar o teste específico:
% BUNDLE_GEMFILE= ' gemfiles/active_record_50.gemfile ' bundle install
% BUNDLE_GEMFILE= ' gemfiles/active_record_50.gemfile ' TEST=kaminari-core/test/requests/navigation_test.rb bundle exec rake test
Copyright (C) 2011- Akira Matsuda. Consulte o MIT-License para obter mais detalhes.