Reputation: 103
Is there a more concise way to write the following nested conditionals?
def sort_column
if Product.column_names.include?(params[:sort])
if params[:sort] == "price_latest" || params[:sort] == "price_average"
"#{params[:sort]}->'#{cookies[:store_id]}'"
else
params[:sort]
end
else
"name"
end
end
Upvotes: 1
Views: 121
Reputation: 110755
A linear search is required to determine if Product.column_names
contains a given element. If that array is large and will not change during execution of the code, and sort_column
is to be called multiple times, performance can be improved by converting that array to a set. Determining whether a set contains a given element is very fast, lookup times being comparable to those for determining if a hash has a given key.
require 'set'
names_set = Product.column_names.to_set
def sort_column(params, names_set)
ps = params[:sort]
return "name" unless names_set.include?(ps)
["price_latest", "price_average"].include?(ps) ?
"#{ps}->'#{cookies[:store_id]}'" : "home"
end
Upvotes: 0
Reputation: 121020
With early return
and case
.
def sort_column
return "name" unless Product.column_names.include?(params[:sort])
case params[:sort]
when "price_latest", "price_average"
"#{params[:sort]}->'#{cookies[:store_id]}'"
else
params[:sort]
end
end
Upvotes: 1
Reputation: 33491
You can replace the if-else
conditions by guard clause, altering the statement depending on the case (if
, unless
):
def sort_column
sort = params[:sort]
return 'name' unless Product.column_names.include?(sort)
return "#{sort}->'#{cookies[:store_id]}'" if sort.in?(%w[price_latest price_average])
sort
end
With return name unless ...
you get rid of if Product.column_names.include?(params[:sort]) else ... end
.
With sort.in?(%w[price_latest price_average])
you shorten the params[:sort] == "price_latest" || params[:sort] == "price_average"
condition and return #{sort}->'#{cookies[:store_id]}'"
just if it returns true.
If none of the other conditions are evaluated as true, return just the value of params[:sort]
.
Upvotes: 2