Class: BookReadingTrackerGem::BookService

Inherits:
Object
  • Object
show all
Defined in:
lib/book_reading_tracker_gem/services/book_service.rb

Class Method Summary collapse

Class Method Details

.add_book(title, author, total_pages, description = nil, isbn = nil, published_year = nil) ⇒ Object



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# File 'lib/book_reading_tracker_gem/services/book_service.rb', line 9

def self.add_book(title, author, total_pages, description = nil, isbn = nil, published_year = nil)
  DatabaseConnection.connect
  book = Book.create!(
    title: title,
    description: description,
    isbn: isbn,
    published_year: published_year
  )
  book.authors.create!(author_name: author)
  book.create_reading_progress!(total_pages: total_pages)
  puts "Add book: #{book.title} successfully"
rescue StandardError => e
  puts "Error adding book: #{e.message}"
ensure
  DatabaseConnection.disconnect
end

.list_booksObject



113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
# File 'lib/book_reading_tracker_gem/services/book_service.rb', line 113

def self.list_books
  DatabaseConnection.connect
  books = Book.includes(:authors).all

  if books.empty?
    puts 'No books in the system.'
    return
  end

  header = %w[id title description isbn published_year authors created_at updated_at]

  rows = books.map do |book|
    # Giới hạn lại thông tin để tránh bảng rộng bị -> dọc
    author_names = (book.authors.map(&:author_name).join(', ').then { |a| a.empty? ? 'N/A' : "#{a[0..20]}..." })

    # Giới hạn mô tả để tránh bảng quá rộng
    description = "#{(book.description || 'N/A')[0..30]}..."
    title = "#{(book.title || 'N/A')[0..20]}..."

    [
      book.id,
      title,
      description,
      book.isbn || 'N/A',
      book.published_year || 'N/A',
      author_names,
      book.created_at,
      book.updated_at
    ]
  end

  # Gọi hàm render_table từ CommonUtils với chế độ ép ngang
  CommonUtils.render_table(header, rows)
rescue StandardError => e
  puts "Error listing books: #{e.message}"
ensure
  DatabaseConnection.disconnect
end

.remove_book(id) ⇒ Object



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/book_reading_tracker_gem/services/book_service.rb', line 26

def self.remove_book(id)
  DatabaseConnection.connect
  book = Book.find_by(id: id)
  if book
    book.reading_progress&.destroy
    book.book_authors.destroy_all
    book.destroy
    puts "Removed book: #{id}."
  else
    puts "Book not found: #{id}."
  end
rescue StandardError => e
  puts "Error removing book: #{e.message}"
ensure
  DatabaseConnection.disconnect
end

.show_progress(id) ⇒ Object



169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
# File 'lib/book_reading_tracker_gem/services/book_service.rb', line 169

def self.show_progress(id)
  DatabaseConnection.connect
  book = Book.includes(:reading_progress).find_by(id: id)

  if book.nil?
    puts "Book not found: #{id}"
    return
  end

  if book.reading_progress.nil?
    puts "No reading progress for '#{book.title}'."
  else
    header = %w[id book_id status pages_read total_pages read created_at updated_at]
    progress = book.reading_progress
    pages_read = progress.pages_read
    total_pages = progress.total_pages
    read = "#{pages_read}/#{total_pages}"

    rows = [
      [
        book.id,
        book.title,
        progress.status,
        pages_read,
        total_pages,
        read,
        book.reading_progress.created_at,
        book.reading_progress.updated_at
      ]
    ]

    CommonUtils.render_table(header, rows)
  end
rescue StandardError => e
  puts "Error showing progress: #{e.message}"
ensure
  DatabaseConnection.disconnect
end

.statsObject



152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
# File 'lib/book_reading_tracker_gem/services/book_service.rb', line 152

def self.stats
  DatabaseConnection.connect
  total_books = Book.count
  read_books = ReadingProgress.where(status: 'read').count
  reading_books = ReadingProgress.where(status: 'reading').count
  unread_books = ReadingProgress.where(status: 'unread').count

  puts "Total books: #{total_books}"
  puts "Books read: #{read_books}"
  puts "Books reading: #{reading_books}"
  puts "Books unread: #{unread_books}"
rescue StandardError => e
  puts "Error generating stats: #{e.message}"
ensure
  DatabaseConnection.disconnect
end

.update_progress(id, pages_read) ⇒ Object



70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/book_reading_tracker_gem/services/book_service.rb', line 70

def self.update_progress(id, pages_read)
  if pages_read.negative?
    puts 'Pages read cannot be negative.'
    return
  end

  DatabaseConnection.connect
  book = Book.find_by(id: id)

  if book.nil?
    puts "Book not found: #{id}"
    return
  end

  reading_progress = book.reading_progress
  if reading_progress.nil?
    puts "No reading progress for '#{book.title}'."
    return
  end

  total_pages = reading_progress.total_pages

  if pages_read > total_pages
    puts "Pages read: #{pages_read} cannot exceed total pages: #{total_pages}."
    return
  end

  reading_progress.update!(pages_read: pages_read)
  puts "Updated reading progress for '#{book.title}' to page #{pages_read}."

  if pages_read.zero?
    update_status(id, 'unread')
  elsif pages_read < total_pages
    update_status(id, 'reading')
  elsif pages_read == total_pages
    update_status(id, 'read')
  end
rescue StandardError => e
  puts "Error updating progress: #{e.message}"
ensure
  DatabaseConnection.disconnect
end

.update_status(id, status) ⇒ Object



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/book_reading_tracker_gem/services/book_service.rb', line 43

def self.update_status(id, status)
  valid_statuses = %w[unread reading read]
  unless valid_statuses.include?(status)
    puts "Invalid status. Accepted: #{valid_statuses.join(', ')}"
    return
  end

  DatabaseConnection.connect
  book = Book.find_by(id: id)
  if book.nil?
    puts "Book not found: #{id}"
    return
  end

  if book.reading_progress.nil?
    puts "No reading progress for '#{book.title}'."
    return
  end

  book.reading_progress.update!(status: status)
  puts "Updated status of '#{book.title}' to '#{status}'."
rescue StandardError => e
  puts "Error updating status: #{e.message}"
ensure
  DatabaseConnection.disconnect
end