Skip to content

Commit

Permalink
Refactored the controller and view for Books Search (#101)
Browse files Browse the repository at this point in the history
Reasons:
- The logic to compose the ransack query was added in the controller action and thus is contributing to a fat controller (that already is) => extracted the composition of the query into an object
- The form works functionally but would need some small UI tweaks to make it look better => Refactored the Search field to improve UI
  • Loading branch information
lucianghinda authored Sep 5, 2023
1 parent 2e79307 commit c41bb23
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 22 deletions.
14 changes: 6 additions & 8 deletions app/controllers/books_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,15 @@ class BooksController < ApplicationController
before_action :set_book, only: %i[show edit update destroy]

layout "admin", only: %i[new edit]

def index
set_meta_tags title: "#{Book.count} books about Ruby & Ruby on Rails", description: "The largest collection of books about Ruby & Ruby on Rails. Find books that will help you learn new versions of Ruby 3, Ruby on Rails 7, Hotwire, TurboFrame, and become a better programmer in general", keywords: 'Book, Ruby, Ruby 3, Ruby on Rails 7, Ruby on Rails 6, Hotwire, Turbo Frame, Stimulus, Vue with Rails, React with Rails, Tailwind with Rails, learn ruby, learn ruby on rails'

@tags = Tag.all.order(:title)
filtered_books = Book.ransack(title_cont: search_term).result
filtered_books = filtered_books.order(created_at: :desc)

@pagy, @books = pagy(filtered_books)
@pagy, @books = pagy(filter.filter(search_term))
@featured = Book.where(featured: true).where(free: false)
@random = Book.where(id: Book.pluck(:id).sample)
@random = Book.where(id: Book.pluck(:id).sample)

render layout:"index_page"
render layout: "index_page"
end

def new
Expand Down Expand Up @@ -84,4 +80,6 @@ def authenticate_admin!
def search_term
params[:search_term]&.strip&.downcase
end

def filter = Filter.new(Book)
end
19 changes: 19 additions & 0 deletions app/models/filter.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# frozen_string_literal: true

class Filter
ORDER_BY_FIELD = :created_at
ORDER_BY_DIRECTION = :desc

def initialize(scope)
@scope = scope
end

def filter(search_term) = search(search_term).order(order_by)

private
attr_reader :scope

def search(search_term) = scope.ransack(title_cont: search_term).result

def order_by = { ORDER_BY_FIELD => ORDER_BY_DIRECTION }
end
28 changes: 14 additions & 14 deletions app/views/books/_index_nav.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,8 @@
<strong>Search Term: </strong><%= params[:search_term] %>
</div>
<% end %>

<div class="flex flex-wrap justify-between mb-8 xl:mb-16 gap-x-8 gap-y-2 md:gap-8">
<div class="flex flex-wrap gap-y-2 gap-8">
<div class="flex flex-wrap gap-8 gap-y-2">
<span class="h2">
<%= link_to_unless_current "All Books", books_path, class: "text-red-500 hover:text-red-600" %>
</span>
Expand All @@ -19,26 +18,27 @@
<%= link_to_unless_current "Testing", "/learn/testing", class: "text-red-500 hover:text-red-600" %>
</span>
</div>

<span>
<%= form_tag(books_path, method: "get", id: 'search_form', remote: true) do %>
<div class="input-group">
<span class="input-group-append">
<%= text_field_tag(:search_term, nil, placeholder: 'Search name', class: 'form-control', value: html_escape(params[:search_term])) %>
</span>
<span class="input-group-append">
<button type="submit" class="btn btn-primary button-rounded", id="submit-search-btn", title="Search Books">Search</button>
<%= link_to books_path, type: :submit, class: "btn btn-warning", id: "clear-search-btn", title: "Reset", style: "margin-left: 10px; color: black" do %> X <% end %>
</span>
<div class="flex items-center gap-2">
<label for="email" class="sr-only">Email</label>
<%= text_field_tag(:search_term, nil, placeholder: 'Search name', class: '"block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6"', value: html_escape(params[:search_term])) %>
<button type="submit" class="rounded-md bg-indigo-600 px-2.5 py-1.5 text-sm font-semibold text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600">Search</button>
<% if params[:search_term].present? %>
<%= link_to books_path, type: :submit, class: "rounded-full p-1.5 text-indigo-600 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600", id: "clear-search-btn", title: "Reset search" do %>
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-5 h-5">
<path stroke-linecap="round" stroke-linejoin="round" d="M9.75 9.75l4.5 4.5m0-4.5l-4.5 4.5M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
<% end %>
<% end %>
</div>
<% end %>
<% end %>
</span>

<span class="h2">
<% @random.each do |item| %>
<%= link_to item, title: "Random Book", class: "text-red-500 hover:scale-110 transition" do %>
🍀
<% end %>
<% end %>
<% end %>
</span>
</div>

0 comments on commit c41bb23

Please sign in to comment.