From 3439fed5813be38dd579ef9e86e81f12000e2e6b Mon Sep 17 00:00:00 2001 From: atiugaev Date: Thu, 6 Mar 2025 22:27:50 +0300 Subject: [PATCH 1/3] add tool-versions and gem alba --- .tool-versions | 1 + Gemfile | 3 +++ Gemfile.lock | 3 +++ 3 files changed, 7 insertions(+) create mode 100644 .tool-versions diff --git a/.tool-versions b/.tool-versions new file mode 100644 index 0000000..3294aed --- /dev/null +++ b/.tool-versions @@ -0,0 +1 @@ +ruby 3.3.0 diff --git a/Gemfile b/Gemfile index fc76bca..cd4eabb 100644 --- a/Gemfile +++ b/Gemfile @@ -29,6 +29,9 @@ gem 'activeadmin' gem 'activeadmin_addons' gem 'devise' +# serializer +gem 'alba' + group :development, :test do gem 'bundler-audit' gem 'capybara' diff --git a/Gemfile.lock b/Gemfile.lock index d66b198..ce0b383 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -95,6 +95,8 @@ GEM uri (>= 0.13.1) addressable (2.8.7) public_suffix (>= 2.0.2, < 7.0) + alba (3.5.0) + ostruct (~> 0.6) arbre (1.7.0) activesupport (>= 3.0.0) ruby2_keywords (>= 0.0.2) @@ -448,6 +450,7 @@ DEPENDENCIES activeadmin activeadmin_addons activerecord-import + alba bundler-audit capybara config From 5aa95d5acd735258c791b63f41a8849db6d74c29 Mon Sep 17 00:00:00 2001 From: atiugaev Date: Fri, 7 Mar 2025 17:18:07 +0300 Subject: [PATCH 2/3] homework_1 --- app/controllers/application_controller.rb | 10 ++++++ app/controllers/books_controller.rb | 9 +++++ app/serializers/application_serializer.rb | 7 ++++ app/serializers/book_serializer.rb | 3 ++ config/database.yml | 1 + config/routes.rb | 3 +- spec/controllers/books_controller_spec.rb | 41 +++++++++++++++++++++++ 7 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 app/controllers/books_controller.rb create mode 100644 app/serializers/application_serializer.rb create mode 100644 app/serializers/book_serializer.rb create mode 100644 spec/controllers/books_controller_spec.rb diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 0d95db2..cfa49b1 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -1,4 +1,14 @@ class ApplicationController < ActionController::Base # Only allow modern browsers supporting webp images, web push, badges, import maps, CSS nesting, and CSS :has. allow_browser versions: :modern + + private + + def serialize(obj, with: nil) + serializer = with || begin + model = obj.try(:model) || obj.class + "#{model.name}Serializer".constantize + end + serializer.new(obj).serialize + end end diff --git a/app/controllers/books_controller.rb b/app/controllers/books_controller.rb new file mode 100644 index 0000000..001e38d --- /dev/null +++ b/app/controllers/books_controller.rb @@ -0,0 +1,9 @@ +class BooksController < ApplicationController + def index + books = Book.all.order(:created_at).limit(::Settings.app.items_per_page) + page = params[:page].to_i + books = books.offset(page * ::Settings.app.items_per_page) if page > 1 + + render json: serialize(books) + end +end diff --git a/app/serializers/application_serializer.rb b/app/serializers/application_serializer.rb new file mode 100644 index 0000000..da9b81d --- /dev/null +++ b/app/serializers/application_serializer.rb @@ -0,0 +1,7 @@ +class ApplicationSerializer + include Alba::Serializer + + def self.one(name, **options) + options[:resource] ||= proc { "#{_1.class.name}Serializer".constantize } + end +end diff --git a/app/serializers/book_serializer.rb b/app/serializers/book_serializer.rb new file mode 100644 index 0000000..114aa27 --- /dev/null +++ b/app/serializers/book_serializer.rb @@ -0,0 +1,3 @@ +class BookSerializer < ApplicationSerializer + attributes :id, :title, :series, :serno, :libid, :size, :filename, :ext, :del, :insno, :published_at, :created_at, :updated_at +end diff --git a/config/database.yml b/config/database.yml index 48f30ee..4277af8 100644 --- a/config/database.yml +++ b/config/database.yml @@ -17,6 +17,7 @@ development: test: <<: *default + <<: *postgre database: library_test production: diff --git a/config/routes.rb b/config/routes.rb index ae608d2..0ef66eb 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -20,10 +20,11 @@ # # end # end + resources :books, only: :index + # Reveal health status on /up that returns 200 if the app boots with no exceptions, otherwise 500. # Can be used by load balancers and uptime monitors to verify that the app is live. get 'up' => 'rails/health#show', as: :rails_health_check - # Render dynamic PWA files from app/views/pwa/* get 'service-worker' => 'rails/pwa#service_worker', as: :pwa_service_worker get 'manifest' => 'rails/pwa#manifest', as: :pwa_manifest diff --git a/spec/controllers/books_controller_spec.rb b/spec/controllers/books_controller_spec.rb new file mode 100644 index 0000000..47ba0d1 --- /dev/null +++ b/spec/controllers/books_controller_spec.rb @@ -0,0 +1,41 @@ +RSpec.describe BooksController, type: :controller do + let(:per_page) { ::Settings.app.items_per_page } + + describe 'GET #index' do + context 'when without page' do + before { get :index } + + it 'responds with ok status' do + expect(response).to have_http_status :ok + end + + it 'responds first 20 books' do + expect(JSON.parse(response.body).size).to eq(per_page) + end + end + + context 'when with page' do + before { get :index, params: { page: 3 } } + + it 'responds with ok status' do + expect(response).to have_http_status :ok + end + + it 'returns other 20 books' do + expect(JSON.parse(response.body).size).to eq(per_page) + end + end + + context 'when page too big' do + before { get :index, params: { page: (Book.count / per_page + per_page) } } + + it 'responds with ok status' do + expect(response).to have_http_status :ok + end + + it 'returns 0 books' do + expect(JSON.parse(response.body).size).to eq(0) + end + end + end +end From 7a76aff543fd4c524e5c0c6bb92f717fe24123bf Mon Sep 17 00:00:00 2001 From: atiugaev Date: Sun, 9 Mar 2025 18:10:05 +0300 Subject: [PATCH 3/3] fix after review --- app/controllers/books_controller.rb | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/app/controllers/books_controller.rb b/app/controllers/books_controller.rb index 001e38d..7032093 100644 --- a/app/controllers/books_controller.rb +++ b/app/controllers/books_controller.rb @@ -1,9 +1,17 @@ class BooksController < ApplicationController def index - books = Book.all.order(:created_at).limit(::Settings.app.items_per_page) - page = params[:page].to_i - books = books.offset(page * ::Settings.app.items_per_page) if page > 1 + books = Book.order(:created_at).limit(per_page).offset(page * per_page) render json: serialize(books) end + + private + + def per_page + ::Settings.app.items_per_page + end + + def page + [ params[:page].to_i, 0 ].max + end end