Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Design pattern - Form Object #69

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Include any files or directories that you don't want to be copied to your
# container here (e.g., local build artifacts, temporary files, etc.).
#
# For more help, visit the .dockerignore file reference guide at
# https://docs.docker.com/go/build-context-dockerignore/

**/.DS_Store
**/__pycache__
**/.venv
**/.classpath
**/.dockerignore
**/.env
**/.git
**/.gitignore
**/.project
**/.settings
**/.toolstarget
**/.vs
**/.vscode
**/*.*proj.user
**/*.dbmdl
**/*.jfm
**/bin
**/charts
**/docker-compose*
**/compose.y*ml
**/Dockerfile*
**/node_modules
**/npm-debug.log
**/obj
**/secrets.dev.yaml
**/values.dev.yaml
LICENSE
README.md
16 changes: 16 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
FROM ruby:3.2.2

RUN apt-get update -qq && apt-get install -y build-essential apt-utils libpq-dev nodejs default-mysql-client

WORKDIR /app

RUN gem install bundler

COPY Gemfile* ./

RUN bundle install

COPY . .

EXPOSE 3000
CMD ["rails", "server", "-b", "0.0.0.0"]
3 changes: 3 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ gem "caxlsx"
gem "caxlsx_rails"
gem "config"
gem "devise"
gem "elasticsearch", "~> 7.10"
gem "elasticsearch-model", "~> 7.0"
gem "elasticsearch-rails", "~> 7.0"
gem "faker", "2.21.0"
gem "figaro"
gem "font-awesome-sass"
Expand Down
26 changes: 26 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,20 @@ GEM
dotenv-rails (3.1.2)
dotenv (= 3.1.2)
railties (>= 6.1)
elasticsearch (7.17.11)
elasticsearch-api (= 7.17.11)
elasticsearch-transport (= 7.17.11)
elasticsearch-api (7.17.11)
multi_json
elasticsearch-model (7.2.1)
activesupport (> 3)
elasticsearch (~> 7)
hashie
elasticsearch-rails (7.2.1)
elasticsearch-transport (7.17.11)
base64
faraday (>= 1, < 3)
multi_json
erubi (1.12.0)
et-orbi (1.2.11)
tzinfo
Expand All @@ -149,6 +163,12 @@ GEM
railties (>= 5.0.0)
faker (2.21.0)
i18n (>= 1.8.11, < 2)
faraday (2.12.0)
faraday-net_http (>= 2.0, < 3.4)
json
logger
faraday-net_http (3.3.0)
net-http
ffi (1.17.0-x86_64-linux-gnu)
figaro (1.2.0)
thor (>= 0.14.0, < 2)
Expand All @@ -165,6 +185,7 @@ GEM
i18n (>= 0.7)
multi_json
request_store (>= 1.0)
hashie (5.0.0)
htmlentities (4.3.4)
httpclient (2.8.3)
i18n (1.14.1)
Expand Down Expand Up @@ -207,6 +228,8 @@ GEM
msgpack (1.7.2)
multi_json (1.15.0)
mysql2 (0.5.5)
net-http (0.4.1)
uri
net-imap (0.3.7)
date
net-protocol
Expand Down Expand Up @@ -432,6 +455,9 @@ DEPENDENCIES
debug
devise
dotenv-rails
elasticsearch (~> 7.10)
elasticsearch-model (~> 7.0)
elasticsearch-rails (~> 7.0)
factory_bot_rails
faker (= 2.21.0)
figaro
Expand Down
20 changes: 12 additions & 8 deletions app/controllers/admin/authors_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,25 +15,27 @@ def show
end

def new
@author = Author.new
@form = AuthorForm.new(Author.new)
@breadcrumb_items = [
{name: t(".index.title"), url: admin_authors_path},
{name: t(".new.title")}
]
end

def create
@author = Author.new author_params
if @author.save
@form = AuthorForm.new(Author.new, author_params)

if @form.save
flash[:success] = t "message.authors.created"
redirect_to admin_author_path(@author), status: :see_other
redirect_to admin_author_path(@form.author), status: :see_other
else
flash[:danger] = t "message.authors.create_fail"
render :new, status: :unprocessable_entity
end
end

def edit
@form = AuthorForm.new(@author)
@breadcrumb_items = [
{name: t(".index.title"), url: admin_authors_path},
{name: @author.name, url: admin_author_path(@author)},
Expand All @@ -42,9 +44,11 @@ def edit
end

def update
if @author.update author_params
@form = AuthorForm.new(@author, author_params)

if @form.save
flash[:success] = t "message.authors.updated"
redirect_to admin_author_path(@author)
redirect_to admin_author_path(@form.author), status: :see_other
else
flash[:danger] = t "message.authors.update_fail"
render :edit, status: :unprocessable_entity
Expand All @@ -57,7 +61,7 @@ def destroy
else
flash[:danger] = t "message.authors.delete_fail"
end
redirect_to admin_authors_path
redirect_to admin_authors_path, status: :see_other
end

private
Expand All @@ -67,7 +71,7 @@ def author_params
end

def load_author
@author = Author.find_by id: params[:id]
@author = Author.find_by(id: params[:id])
return if @author

flash[:danger] = t "message.authors.not_found"
Expand Down
12 changes: 6 additions & 6 deletions app/controllers/admin/borrow_books_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ def confirm
else
flash[:danger] = t "message.borrow_books.qty_insufficient"
end
redirect_to borrow_admin_borrow_books_path
redirect_to borrow_admin_borrow_cards_path
end

def cancel
Expand All @@ -31,7 +31,7 @@ def cancel
else
flash[:danger] = t "message.borrow_books.status_fail"
end
redirect_to borrow_admin_borrow_books_path
redirect_to borrow_admin_borrow_cards_path
end

def returned
Expand All @@ -43,7 +43,7 @@ def returned
else
flash[:error] = t "message.borrow_books.status_fail"
end
redirect_to return_admin_borrow_books_path
redirect_to return_admin_borrow_cards_path
end

def lost
Expand All @@ -57,7 +57,7 @@ def lost
flash[:error] = t "message.borrow_books.status_fail"
end

redirect_to return_admin_borrow_books_path
redirect_to return_admin_borrow_cards_path
end

def refresh
Expand All @@ -75,7 +75,7 @@ def refresh
end

flash[:success] = t "message.borrow_books.refresh_success"
redirect_to return_admin_borrow_books_path
redirect_to return_admin_borrow_cards_path
end

private
Expand All @@ -85,7 +85,7 @@ def load_borrow_book
return if @borrow_book

flash[:danger] = t "message.borrow_books.not_found"
redirect_to admin_borrow_books_path
redirect_to admin_borrow_cards_path
end

def activate_overdue_user
Expand Down
16 changes: 12 additions & 4 deletions app/controllers/episodes_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,18 @@ class EpisodesController < ApplicationController
def show; end

def all
@q = Episode.ransack params[:q]
@episodes_search = @q.result distinct: true
@pagy, @episodes = pagy(
@episodes_search,
@q = params[:episode_name]

@search_results = Episode.search_episodes(
name: params[:episode_name],
book_id: params[:book_id],
publisher_id: params[:publisher_id],
author_id: params[:authors_id],
category_id: params[:categories_id]
)

@pagy, @episodes = pagy_array(
@search_results,
limit: Settings.controllers.episodes.all.per_page
)
end
Expand Down
47 changes: 47 additions & 0 deletions app/forms/author_form.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
class AuthorForm
include ActiveModel::Model

attr_accessor :name, :intro, :bio, :dob, :dod, :thumb_img, :author

validates :name, presence: true,
length: {maximum: Settings.models.author.name.max_length}
validates :intro, presence: true,
length: {maximum: Settings.models.author.intro.max_length}
validates :bio, presence: true
validates :dob, presence: true
validate :date_of_death_not_before_date_of_birth

def initialize author = Author.new, attributes = {}
@author = author
@name = author.name
@intro = author.intro
@bio = author.bio
@dob = author.dob
@dod = author.dod
@thumb_img = author.thumb_img

super(attributes)
end

def save
return false unless valid?

author.assign_attributes(attributes.except(:thumb_img))
author.thumb_img.attach(thumb_img) if thumb_img.present?
author.save
end

private

def attributes
{name:, intro:, bio:, dob:, dod:, thumb_img:}
end

def date_of_death_not_before_date_of_birth
return if dod.blank? || dob.blank?

return unless dod < dob

errors.add(:dod, :after_date_of_birth)
end
end
4 changes: 1 addition & 3 deletions app/javascript/custom/form.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,7 @@ document.addEventListener('DOMContentLoaded', function() {

var multiSelects = form.querySelectorAll('select[multiple]');
multiSelects.forEach(function(select) {
for (var i = 0; i < select.options.length; i++) {
select.options[i].selected = false;
}
select.querySelectorAll('option').forEach(option => option.selected = false);

const hiddenInput = select.previousElementSibling;
hiddenInput.value = '';
Expand Down
18 changes: 0 additions & 18 deletions app/models/author.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,6 @@ class Author < ApplicationRecord
has_many :episodes, through: :books
has_one_attached :thumb_img

validates :name, presence: true,
length: {maximum: Settings.models.author.name.max_length}
validates :intro, presence: true,
length: {maximum: Settings.models.author.intro.max_length}
validates :bio, presence: true
validates :dob, presence: true
validate :date_of_death_not_before_date_of_birth

scope :sorted_by_name, ->{order(name: :asc)}
scope :sorted_by_created, ->{order(created_at: :desc)}

Expand All @@ -25,14 +17,4 @@ def self.ransackable_attributes _auth_object = nil
def self.ransackable_associations _auth_object = nil
%w(book_authors books episodes favorites)
end

private

def date_of_death_not_before_date_of_birth
return if dod.blank? || dob.blank?

return unless dod < dob

errors.add(:dod, :after_date_of_birth)
end
end
8 changes: 8 additions & 0 deletions app/models/book.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,14 @@ class Book < ApplicationRecord
scope :sorted_by_name, ->{order(name: :asc)}
scope :sorted_by_created, ->{order(created_at: :desc)}

def author_ids
authors.pluck(:id)
end

def category_ids
categories.pluck(:id)
end

def self.ransackable_attributes _auth_object = nil
%w(created_at id name publisher_id updated_at)
end
Expand Down
28 changes: 28 additions & 0 deletions app/models/concerns/searchable.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
module Searchable
extend ActiveSupport::Concern

included do
include Elasticsearch::Model
include Elasticsearch::Model::Callbacks

settings index: {number_of_shards: 1} do
mappings dynamic: false do
indexes :name, type: "text"
indexes :book_id, type: "keyword"
indexes :publisher_id, type: "keyword"
indexes :author_id, type: "keyword"
indexes :category_id, type: "keyword"
end
end

def as_indexed_json _options = {}
{
name:,
book_id:,
publisher_id: book&.publisher_id,
author_id: book&.author_ids,
category_id: book&.category_ids
}
end
end
end
Loading