I am refactoring a user search that just feels dirty. (Users#search)
I need to allow a blank param to search on partial or only a first or last, but don't want to return all the records in the database (which is what seems to be happening when I search with one value nil).
That said, what's the best way to handle one blank param / nil value? What's the most succinct, efficient way to do this?
Here is where I started:
def user_search ## this is my before_action
if params[:fname] || params[:lname]
@users = User.where("first_name LIKE ? OR last_name LIKE ?", "%#{params[:fname]}%", "%#{params[:lname]}%")
elsif params[:email_search]
@users = User.where("email LIKE ?", "%#{params[:email_search]}%")
end
head 404 if @users.blank?
end
Here is where I am:
def user_search
if params[:fname].presence && params[:lname].presence
@users = User.where("first_name LIKE ? AND last_name LIKE ?", "%#{params[:fname]}%", "%#{params[:lname]}%")
elsif query = (params[:fname] || params[:lname])
@users = User.where("first_name LIKE ? OR last_name LIKE ?", "%#{query}%", "%#{query}%")
elsif params[:email_search]
@users = User.where("email LIKE ?", "%#{params[:email_search]}%")
end
head 404 if @users.blank?
end
The significance behind the SQL of OR versus AND seems to be a convenient way to query and return matches on one of the names, but is it really efficient? Looking for a first_name
in the last_name
column sounds kind of silly hackery. Unless I'm looking at this the wrong way.
Is there a more performant way to do this?
fname
and anlname
field, thenparams[:fname] && params[:lname]
will always be true, even if either field (or both fields) is empty. \$\endgroup\$null
value is evaluated as "undefined
," i.e. "nil
," or so I thought. Does that change things / make more sense? \$\endgroup\$