ページネーションをkaminari、検索をransackに置き換え
This commit is contained in:
parent
6ba87e4ee7
commit
50f2214021
15 changed files with 127 additions and 48 deletions
3
Gemfile
3
Gemfile
|
@ -16,6 +16,9 @@ gem 'sqlite3', '>= 1.4'
|
|||
gem 'solid_cache'
|
||||
gem 'solid_queue'
|
||||
|
||||
gem 'kaminari'
|
||||
gem 'ransack'
|
||||
|
||||
# Use the Puma web server [https://github.com/puma/puma]
|
||||
gem 'puma', '>= 5.0'
|
||||
|
||||
|
|
18
Gemfile.lock
18
Gemfile.lock
|
@ -120,6 +120,18 @@ GEM
|
|||
jbuilder (2.13.0)
|
||||
actionview (>= 5.0.0)
|
||||
activesupport (>= 5.0.0)
|
||||
kaminari (1.2.2)
|
||||
activesupport (>= 4.1.0)
|
||||
kaminari-actionview (= 1.2.2)
|
||||
kaminari-activerecord (= 1.2.2)
|
||||
kaminari-core (= 1.2.2)
|
||||
kaminari-actionview (1.2.2)
|
||||
actionview
|
||||
kaminari-core (= 1.2.2)
|
||||
kaminari-activerecord (1.2.2)
|
||||
activerecord
|
||||
kaminari-core (= 1.2.2)
|
||||
kaminari-core (1.2.2)
|
||||
logger (1.6.6)
|
||||
loofah (2.24.0)
|
||||
crass (~> 1.0.2)
|
||||
|
@ -212,6 +224,10 @@ GEM
|
|||
thor (~> 1.0, >= 1.2.2)
|
||||
zeitwerk (~> 2.6)
|
||||
rake (13.2.1)
|
||||
ransack (4.3.0)
|
||||
activerecord (>= 6.1.5)
|
||||
activesupport (>= 6.1.5)
|
||||
i18n
|
||||
rdoc (6.12.0)
|
||||
psych (>= 4.0.0)
|
||||
regexp_parser (2.10.0)
|
||||
|
@ -305,9 +321,11 @@ DEPENDENCIES
|
|||
debug
|
||||
importmap-rails
|
||||
jbuilder
|
||||
kaminari
|
||||
puma (>= 5.0)
|
||||
rails (= 8.0.1)
|
||||
rails-i18n
|
||||
ransack
|
||||
selenium-webdriver
|
||||
solid_cache
|
||||
solid_queue
|
||||
|
|
|
@ -2,13 +2,11 @@ class MemosController < ApplicationController
|
|||
before_action :set_memo, only: %i[edit update destroy]
|
||||
|
||||
def index
|
||||
page = (params[:page] || 0).to_i
|
||||
@memos = Memo.search(params[:query])
|
||||
.order(created_at: :desc)
|
||||
.limit(4)
|
||||
.offset(page * 4)
|
||||
|
||||
@has_next = Memo.search(params[:query]).count > (page + 1) * 4
|
||||
@q = Memo.ransack(params[:q])
|
||||
@memos = @q.result(distinct: true)
|
||||
.order(created_at: :desc)
|
||||
.page(params[:page])
|
||||
.per(4)
|
||||
|
||||
respond_to do |format|
|
||||
format.html
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
import { Controller } from "@hotwired/stimulus";
|
||||
|
||||
export default class extends Controller {
|
||||
submit() {
|
||||
clearTimeout(this.timeout);
|
||||
this.timeout = setTimeout(() => {
|
||||
this.element.requestSubmit();
|
||||
}, 300);
|
||||
}
|
||||
}
|
|
@ -1,11 +1,11 @@
|
|||
class Memo < ApplicationRecord
|
||||
validates :content, presence: true
|
||||
|
||||
def self.search(query)
|
||||
if query.present?
|
||||
where('content LIKE ?', "%#{query}%").order(created_at: :desc)
|
||||
else
|
||||
order(created_at: :desc)
|
||||
end
|
||||
def self.ransackable_attributes(_auth_object = nil)
|
||||
%w[content created_at id updated_at]
|
||||
end
|
||||
|
||||
def self.ransackable_associations(_auth_object = nil)
|
||||
[]
|
||||
end
|
||||
end
|
||||
|
|
11
app/views/kaminari/_first_page.html.erb
Normal file
11
app/views/kaminari/_first_page.html.erb
Normal file
|
@ -0,0 +1,11 @@
|
|||
<%# Link to the "First" page
|
||||
- available local variables
|
||||
url: url to the first page
|
||||
current_page: a page object for the currently displayed page
|
||||
total_pages: total number of pages
|
||||
per_page: number of items to fetch per page
|
||||
remote: data-remote
|
||||
-%>
|
||||
<span class="first">
|
||||
<%= link_to_unless current_page.first?, t('views.pagination.first').html_safe, url, remote: remote %>
|
||||
</span>
|
8
app/views/kaminari/_gap.html.erb
Normal file
8
app/views/kaminari/_gap.html.erb
Normal file
|
@ -0,0 +1,8 @@
|
|||
<%# Non-link tag that stands for skipped pages...
|
||||
- available local variables
|
||||
current_page: a page object for the currently displayed page
|
||||
total_pages: total number of pages
|
||||
per_page: number of items to fetch per page
|
||||
remote: data-remote
|
||||
-%>
|
||||
<span class="page gap"><%= t('views.pagination.truncate').html_safe %></span>
|
11
app/views/kaminari/_last_page.html.erb
Normal file
11
app/views/kaminari/_last_page.html.erb
Normal file
|
@ -0,0 +1,11 @@
|
|||
<%# Link to the "Last" page
|
||||
- available local variables
|
||||
url: url to the last page
|
||||
current_page: a page object for the currently displayed page
|
||||
total_pages: total number of pages
|
||||
per_page: number of items to fetch per page
|
||||
remote: data-remote
|
||||
-%>
|
||||
<span class="last">
|
||||
<%= link_to_unless current_page.last?, t('views.pagination.last').html_safe, url, remote: remote %>
|
||||
</span>
|
3
app/views/kaminari/_next_page.html.erb
Normal file
3
app/views/kaminari/_next_page.html.erb
Normal file
|
@ -0,0 +1,3 @@
|
|||
<%= link_to_next_page @memos, "気力十分😤",
|
||||
class: "inline-flex items-center px-4 py-2 bg-blue-500 hover:bg-blue-600 text-white font-medium rounded-lg transition-colors duration-200",
|
||||
data: { turbo_frame: "memos" } %>
|
12
app/views/kaminari/_page.html.erb
Normal file
12
app/views/kaminari/_page.html.erb
Normal file
|
@ -0,0 +1,12 @@
|
|||
<%# Link showing page number
|
||||
- available local variables
|
||||
page: a page object for "this" page
|
||||
url: url to this page
|
||||
current_page: a page object for the currently displayed page
|
||||
total_pages: total number of pages
|
||||
per_page: number of items to fetch per page
|
||||
remote: data-remote
|
||||
-%>
|
||||
<span class="page<%= ' current' if page.current? %>">
|
||||
<%= link_to_unless page.current?, page, url, {remote: remote, rel: page.rel} %>
|
||||
</span>
|
15
app/views/kaminari/_paginator.html.erb
Normal file
15
app/views/kaminari/_paginator.html.erb
Normal file
|
@ -0,0 +1,15 @@
|
|||
<%= paginator.render do %>
|
||||
<nav class="flex justify-center space-x-2">
|
||||
<%= first_page_tag unless current_page.first? %>
|
||||
<%= prev_page_tag unless current_page.first? %>
|
||||
<% each_page do |page| %>
|
||||
<% if page.display_tag? %>
|
||||
<%= page_tag page %>
|
||||
<% elsif !page.was_truncated? %>
|
||||
<%= gap_tag %>
|
||||
<% end %>
|
||||
<% end %>
|
||||
<%= next_page_tag unless current_page.last? %>
|
||||
<%= last_page_tag unless current_page.last? %>
|
||||
</nav>
|
||||
<% end %>
|
11
app/views/kaminari/_prev_page.html.erb
Normal file
11
app/views/kaminari/_prev_page.html.erb
Normal file
|
@ -0,0 +1,11 @@
|
|||
<%# Link to the "Previous" page
|
||||
- available local variables
|
||||
url: url to the previous page
|
||||
current_page: a page object for the currently displayed page
|
||||
total_pages: total number of pages
|
||||
per_page: number of items to fetch per page
|
||||
remote: data-remote
|
||||
-%>
|
||||
<span class="prev">
|
||||
<%= link_to_unless current_page.first?, t('views.pagination.previous').html_safe, url, rel: 'prev', remote: remote %>
|
||||
</span>
|
|
@ -1,37 +1,30 @@
|
|||
<div class="mb-8 mt-8">
|
||||
<div class="flex items-center gap-4">
|
||||
<%= form_with url: memos_path, method: :get,
|
||||
data: { turbo_frame: "search-results", controller: "search" } do |f| %>
|
||||
<%= search_form_for @q, html: { data: { turbo_frame: "search-results", controller: "search" } } do |f| %>
|
||||
<div class="relative">
|
||||
<%= f.text_field :query,
|
||||
<%= f.text_field :content_cont,
|
||||
class: "w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-blue-500",
|
||||
placeholder: "検索...",
|
||||
data: { action: "input->search#submit" },
|
||||
value: params[:query] %>
|
||||
data: { action: "input->search#submit" } %>
|
||||
</div>
|
||||
<% end %>
|
||||
<%= link_to new_memo_path, class: "bg-blue-500 hover:bg-blue-600 text-white font-bold py-2 px-4 rounded-lg transition-colors duration-200" do %>
|
||||
<span class="flex items-center">
|
||||
</svg>
|
||||
+ 出力開始
|
||||
</span>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="memos">
|
||||
<%= turbo_frame_tag "memos" do %>
|
||||
<%= turbo_frame_tag "memos" do %>
|
||||
<div id="memos-container" class="flex flex-col gap-4">
|
||||
<%= render @memos %>
|
||||
<%= render "empty_results", query: params[:query] if @memos.empty? %>
|
||||
<%= render "empty_results", query: @q&.content_cont if @memos.empty? %>
|
||||
</div>
|
||||
<% end %>
|
||||
<div id="load-more" class="text-center mt-8">
|
||||
<% if @has_next %>
|
||||
<%= link_to "気力十分😤",
|
||||
memos_path(page: (params[:page] || 0).to_i + 1, query: params[:query]),
|
||||
|
||||
<div class="text-center mt-8">
|
||||
<%= link_to_next_page @memos, "気力十分😤",
|
||||
class: "inline-flex items-center px-4 py-2 bg-blue-500 hover:bg-blue-600 text-white font-medium rounded-lg transition-colors duration-200",
|
||||
data: { turbo_frame: "memos" } %>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
|
|
|
@ -1,11 +1,3 @@
|
|||
<%= turbo_stream.append "memos-container" do %>
|
||||
<%= render @memos %>
|
||||
<% end %>
|
||||
<div id="load-more" class="text-center mt-8">
|
||||
<% if @has_next %>
|
||||
<%= link_to "気力十分😤",
|
||||
memos_path(page: (params[:page] || 0).to_i + 1, query: params[:query]),
|
||||
class: "inline-flex items-center px-4 py-2 bg-blue-500 hover:bg-blue-600 text-white font-medium rounded-lg transition-colors duration-200",
|
||||
data: { turbo_frame: "memos" } %>
|
||||
<% end %>
|
||||
</div>
|
||||
|
|
14
config/initializers/kaminari_config.rb
Normal file
14
config/initializers/kaminari_config.rb
Normal file
|
@ -0,0 +1,14 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
Kaminari.configure do |config|
|
||||
# config.default_per_page = 25
|
||||
# config.max_per_page = nil
|
||||
# config.window = 4
|
||||
# config.outer_window = 0
|
||||
# config.left = 0
|
||||
# config.right = 0
|
||||
# config.page_method_name = :page
|
||||
# config.param_name = :page
|
||||
# config.max_pages = nil
|
||||
# config.params_on_first_page = false
|
||||
end
|
Loading…
Reference in a new issue