diff --git a/Gemfile b/Gemfile index b0a18fc..18d2a8a 100644 --- a/Gemfile +++ b/Gemfile @@ -19,6 +19,9 @@ gem "jbuilder" gem "bcrypt", "~> 3.1" +gem "faker", "~> 3.5" +gem "kaminari", "~> 1.2" + # Use Active Model has_secure_password [https://guides.rubyonrails.org/active_model_basics.html#securepassword] # gem "bcrypt", "~> 3.1.7" diff --git a/Gemfile.lock b/Gemfile.lock index 5f8ef2d..0479d72 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -114,6 +114,8 @@ GEM erubi (1.13.1) et-orbi (1.2.11) tzinfo + faker (3.5.1) + i18n (>= 1.8.11, < 2) ffi (1.17.1-aarch64-linux-gnu) ffi (1.17.1-aarch64-linux-musl) ffi (1.17.1-arm-linux-gnu) @@ -166,6 +168,18 @@ GEM sshkit (>= 1.23.0, < 2.0) thor (~> 1.3) zeitwerk (>= 2.6.18, < 3.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) language_server-protocol (3.17.0.3) listen (3.9.0) rb-fsevent (~> 0.10, >= 0.10.3) @@ -420,11 +434,13 @@ DEPENDENCIES capybara cssbundling-rails (~> 1.4) debug + faker (~> 3.5) guard (~> 2.19) importmap-rails jbuilder jsbundling-rails (~> 1.3) kamal + kaminari (~> 1.2) minitest-reporters propshaft puma (>= 5.0) diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 283124a..0b54b14 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -4,7 +4,9 @@ class UsersController < ApplicationController before_action :correct_user, only: [ :edit, :update ] def index - @users = User.all + # @users = User.all + # @users = User.order(:name).page(params[:page]) + @users = User.page(params[:page]) end def show diff --git a/app/views/kaminari/_first_page.html.erb b/app/views/kaminari/_first_page.html.erb new file mode 100644 index 0000000..2c5985b --- /dev/null +++ b/app/views/kaminari/_first_page.html.erb @@ -0,0 +1,3 @@ +
  • + <%= link_to_unless current_page.first?, raw(t 'views.pagination.first'), url, remote: remote %> +
  • diff --git a/app/views/kaminari/_gap.html.erb b/app/views/kaminari/_gap.html.erb new file mode 100644 index 0000000..6d3a149 --- /dev/null +++ b/app/views/kaminari/_gap.html.erb @@ -0,0 +1,3 @@ +
  • + <%= content_tag :a, raw(t 'views.pagination.truncate') %> +
  • diff --git a/app/views/kaminari/_last_page.html.erb b/app/views/kaminari/_last_page.html.erb new file mode 100644 index 0000000..aee2524 --- /dev/null +++ b/app/views/kaminari/_last_page.html.erb @@ -0,0 +1,3 @@ +
  • + <%= link_to_unless current_page.last?, raw(t 'views.pagination.last'), url, { remote: remote } %> +
  • diff --git a/app/views/kaminari/_next_page.html.erb b/app/views/kaminari/_next_page.html.erb new file mode 100644 index 0000000..8e9a10e --- /dev/null +++ b/app/views/kaminari/_next_page.html.erb @@ -0,0 +1,3 @@ +
  • + <%= link_to_unless current_page.last?, raw(t 'views.pagination.next'), url, rel: 'next', remote: remote %> +
  • diff --git a/app/views/kaminari/_page.html.erb b/app/views/kaminari/_page.html.erb new file mode 100644 index 0000000..47ea75d --- /dev/null +++ b/app/views/kaminari/_page.html.erb @@ -0,0 +1,9 @@ +<% if page.current? %> +
  • + <%= content_tag :a, page, data: { remote: remote }, rel: page.rel %> +
  • +<% else %> +
  • + <%= link_to page, url, remote: remote, rel: page.rel %> +
  • +<% end %> diff --git a/app/views/kaminari/_paginator.html.erb b/app/views/kaminari/_paginator.html.erb new file mode 100644 index 0000000..2c8757b --- /dev/null +++ b/app/views/kaminari/_paginator.html.erb @@ -0,0 +1,15 @@ +<%= paginator.render do -%> + +<% end -%> diff --git a/app/views/kaminari/_prev_page.html.erb b/app/views/kaminari/_prev_page.html.erb new file mode 100644 index 0000000..f16f6b4 --- /dev/null +++ b/app/views/kaminari/_prev_page.html.erb @@ -0,0 +1,3 @@ +
  • + <%= link_to_unless current_page.first?, raw(t 'views.pagination.previous'), url, rel: 'prev', remote: remote %> +
  • diff --git a/app/views/users/_user.html.erb b/app/views/users/_user.html.erb new file mode 100644 index 0000000..d54c0e3 --- /dev/null +++ b/app/views/users/_user.html.erb @@ -0,0 +1,4 @@ +
  • + <%= gravatar_for user, size: 50 %> + <%= link_to user.name, user %> +
  • \ No newline at end of file diff --git a/app/views/users/index.html.erb b/app/views/users/index.html.erb index 26ad418..d0ba40a 100644 --- a/app/views/users/index.html.erb +++ b/app/views/users/index.html.erb @@ -2,11 +2,16 @@

    All users

    +<%= paginate @users %> + + \ No newline at end of file + <%= render @users %> + <%# auto loop by rails, like after %> + <%# @users.each do |user| %> + + <%#= gravatar_for user, size: 50 %> + <%#= link_to user.name, user %> + + <%# end %> + diff --git a/config/initializers/kaminari_config.rb b/config/initializers/kaminari_config.rb new file mode 100644 index 0000000..f476199 --- /dev/null +++ b/config/initializers/kaminari_config.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +Kaminari.configure do |config| + config.default_per_page = 5 + # 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 diff --git a/config/locales/en.yml b/config/locales/en.yml index 6c349ae..4e65d5c 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -28,4 +28,4 @@ # enabled: "ON" en: - hello: "Hello world" + hello: "Hello world" \ No newline at end of file diff --git a/db/seeds.rb b/db/seeds.rb index 4fbd6ed..155583d 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -7,3 +7,18 @@ # ["Action", "Comedy", "Drama", "Horror"].each do |genre_name| # MovieGenre.find_or_create_by!(name: genre_name) # end + +User.create!(name: "Example User", + email: "example@example.com", + password: "foobar", + password_confirmation: "foobar") + +99.times do |n| + name = Faker::Name.name + email = "example-#{n+1}@railstutorial.org" + password = "password" + User.create!(name: name, + email: email, + password: password, + password_confirmation: password) +end diff --git a/test/fixtures/users.yml b/test/fixtures/users.yml index bfcca93..2f60abe 100644 --- a/test/fixtures/users.yml +++ b/test/fixtures/users.yml @@ -12,4 +12,11 @@ michael: archer: name: Sterling Archer email: suchess@example.gov - password_digest: <%= User.digest('password') %> \ No newline at end of file + password_digest: <%= User.digest('password') %> + +<% 30.times do |n| %> +user_<%= n %>: + name: <%= "user #{n}" %> + email: <%= "user-#{n}@example.com" %> + password_digest: <%= User.digest('password') %> +<% end %> \ No newline at end of file diff --git a/test/integration/users_index_test.rb b/test/integration/users_index_test.rb new file mode 100644 index 0000000..a2064d1 --- /dev/null +++ b/test/integration/users_index_test.rb @@ -0,0 +1,17 @@ +require "test_helper" + +class UsersIndexTest < ActionDispatch::IntegrationTest + def setup + @user = users(:michael) + end + + test "index including pagination" do + log_in_as(@user) + get users_path + assert_template "users/index" + assert_select "ul.pagination" + User.page(1).each do |user| + assert_select "a[href=?]", user_path(user), text: user.name + end + end +end diff --git a/test/integration/users_login_test.rb b/test/integration/users_login_test.rb index fab2475..bddac37 100644 --- a/test/integration/users_login_test.rb +++ b/test/integration/users_login_test.rb @@ -39,6 +39,7 @@ class UsersLoginTest < ActionDispatch::IntegrationTest assert_template "users/show" assert_select "a[href=?]", login_path, count: 0 assert_select "a[href=?]", logout_path + assert_select "a[href=?]", users_path assert_select "a[href=?]", user_path(@user) delete logout_path assert_not is_logged_in?