summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/controllers/api/products_controller.rb9
-rw-r--r--app/queries/searches/base_search.rb12
-rw-r--r--app/queries/searches/product_search.rb16
-rw-r--r--app/queries/searches/scope_filters/product_scope_filter.rb65
4 files changed, 100 insertions, 2 deletions
diff --git a/app/controllers/api/products_controller.rb b/app/controllers/api/products_controller.rb
index 9ebdac8..59019d0 100644
--- a/app/controllers/api/products_controller.rb
+++ b/app/controllers/api/products_controller.rb
@@ -10,7 +10,8 @@ module Api
end
def index
- @products = Product.all
+ @search = Searches::ProductSearch.new(scope, search_params)
+ @products = @search.call
render json: serialized_collection.serializable_hash, status: :ok
end
@@ -59,7 +60,7 @@ module Api
end
def serialized_collection
- ProductSerializer.new(scope.page(params[:page]))
+ ProductSerializer.new(@products.page(params[:page]))
end
def permitted_params
@@ -72,5 +73,9 @@ module Api
public_id = SecureRandom.hex(12) while Product.exists?(public_id:)
permitted_params.merge(categories:, public_id:)
end
+
+ def search_params
+ params.permit(:name, :company, :category, :quantity, :bulk_price, :price)
+ end
end
end
diff --git a/app/queries/searches/base_search.rb b/app/queries/searches/base_search.rb
new file mode 100644
index 0000000..b8c49d4
--- /dev/null
+++ b/app/queries/searches/base_search.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+module Searches
+ # BaseSearch
+ class BaseSearch
+ def initialize(scope, params)
+ @scope = scope
+ @params = params
+ @scope_filter = ScopeFilters::ProductScopeFilter.new(scope, @params)
+ end
+ end
+end
diff --git a/app/queries/searches/product_search.rb b/app/queries/searches/product_search.rb
new file mode 100644
index 0000000..d426211
--- /dev/null
+++ b/app/queries/searches/product_search.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+module Searches
+ # ProductSearch
+ class ProductSearch < BaseSearch
+ def call
+ @scope_filter.by_name
+ .by_company
+ .by_category
+ .order_by_available_quantity
+ .order_by_price
+ .order_by_bulk_price
+ .query_result
+ end
+ end
+end
diff --git a/app/queries/searches/scope_filters/product_scope_filter.rb b/app/queries/searches/scope_filters/product_scope_filter.rb
new file mode 100644
index 0000000..d6f254d
--- /dev/null
+++ b/app/queries/searches/scope_filters/product_scope_filter.rb
@@ -0,0 +1,65 @@
+# frozen_string_literal: true
+
+module Searches
+ module ScopeFilters
+ # ProductScopeFilter
+ class ProductScopeFilter
+ def initialize(scope, params)
+ @scope = scope
+ @params = params
+ end
+
+ def query_result
+ @scope
+ end
+
+ def order_by_price
+ return self unless invalid_order_by_param(:price)
+
+ @scope = @scope.order(unitary_price: @params[:price].to_sym)
+ self
+ end
+
+ def order_by_bulk_price
+ return self unless invalid_order_by_param(:bulk_price)
+
+ @scope = @scope.order(bulk_price: @params[:bulk_price].to_sym)
+ self
+ end
+
+ def by_category
+ return self unless @params[:category].present?
+
+ @scope = @scope.where("'categories' LIKE ?", "%#{@params[:category]}%")
+ self
+ end
+
+ def order_by_available_quantity
+ return self unless invalid_order_by_param(:quantity)
+
+ @scope = @scope.order(available_quantity: @params[:quantity].to_sym)
+ self
+ end
+
+ def by_company
+ return self unless @params[:company].present?
+
+ @scope = @scope.where('companies.short_name = ?', "#{@params[:company]}")
+ self
+ end
+
+ def by_name
+ return self unless @params[:name].present?
+
+ @scope = @scope.where('LOWER(products.name) LIKE ?', "%#{@params[:name]}%")
+ self
+ end
+
+ private
+
+ def invalid_order_by_param(param_symbol)
+ @params[param_symbol].present? || %w[asc desc].include?(@params[param_symbol])
+ end
+ end
+ end
+end