Topic: Refactor a db search based on received params

Hello dear forum members,I'm hoping someone can help me to refactor this long code using some ruby sweetness.  I think it is possible but I don't know exactly how to abstract the common parts.  Basically I'm sending the db column that the  user desires to search in a param such asparams[:titulo]   so I check if this param arrived from the browser, and if so run the mysql search, paginate, and throw it into my @ventas variable for display (actually send out via AJAX/JSON).My overall approach might be wrong as well, but for starters I'd love it just to reduce the repetitiveness seen below (I have about 15 of these constructs for each column that is searchable):

if titulo = params[:titulo].presence 
  @ventas = Venta.paginate(:conditions => ["titulo like ?", "%"+titulo+"%"] ,:page => params[:page], :per_page => params[:rows], :order => "#{params[:sidx]} #{params[:sord]}")  
         
end
                    
if tipo_de_actividad  = params[:tipo_de_actividad].presence
  @ventas = Venta.paginate(:conditions => ["tipo_de_actividad like ?", "%"+tipo_de_actividad+"%"] ,:page => params[:page], :per_page => params[:rows], :order => "#{params[:sidx]} #{params[:sord]}")  

end

Re: Refactor a db search based on received params

anybody?? help!!!

perhaps there is a better way to find out which parameter (equivalent to db column) is set in the POST and go from there?

Re: Refactor a db search based on received params

At first I think that ":conditions => ["titulo like ?", "%"+titulo+"%"]" that would look better if change it on:
:conditions => ["titulo like '%?%'",  titulo]
I'm not in the context of your method, but check if that variables are used: titulo, tipo_de_actividad
Also I've noticed repeating fragments:
@ventas = Venta.paginate(:conditions => ["titulo like ?", "%"+titulo+"%"] ,:page => params[:page], :per_page => params[:rows], :order => "#{params[:sidx]} #{params[:sord]}")
@ventas = Venta.paginate(:conditions => ["tipo_de_actividad like ?", "%"+tipo_de_actividad+"%"] ,:page => params[:page], :per_page => params[:rows], :order => "#{params[:sidx]} #{params[:sord]}")

You can move it to method:
def venta_list(condition_name, condition, options)
  Venta.paginate(:conditions => ["#{condition_name} like '%?%'",  condition] ,:page => options[:page], :per_page => options[:rows], :order => "#{options[:sidx]} #{options[:sord]}")
end

So for first refactoring i propose to change it on:
if titulo = params[:titulo]
  @ventas = venta_list 'titulo', titulo, params
end

if tipo_de_actividad  = params[:tipo_de_actividad]
  @ventas = venta_list 'tipo_de_actividad', tipo_de_actividad, params
end

def venta_list(condition_name, condition, options)
  Venta.paginate(:conditions => ["#{condition_name} like '%?%'",  condition] ,:page => options[:page], :per_page => options[:rows], :order => "#{options[:sidx]} #{options[:sord]}")
end

Last edited by KindBug (2012-02-17 03:56:04)

Re: Refactor a db search based on received params

Also we can refactor method by removing redundant param:
def venta_list(condition_name, options)
  Venta.paginate(:conditions => ["#{condition_name} like '%?%'",  options[condition_name._to_sym] ,:page => options[:page], :per_page => options[:rows], :order => "#{options[:sidx]} #{options[:sord]}")
end

if params[:titulo]
  @ventas = venta_list 'titulo', params
end
if params[:tipo_de_actividad]
  @ventas = venta_list 'tipo_de_actividad', params
end

Last edited by KindBug (2012-02-17 03:59:34)

Re: Refactor a db search based on received params

Also conditions could be inlined:
@ventas = venta_list('titulo', params) if params[:titulo]
@ventas = venta_list('tipo_de_actividad', params) if params[:tipo_de_actividad]
And you can put it into array to compress it:
['titulo', 'tipo_de_actividad'].each do |condition|
  @ventas = venta_list(condition, params) if params[condition.to_sym]
end
I think it could work even without to_sym, so:
['titulo', 'tipo_de_actividad'].each do |condition|
  @ventas = venta_list(condition, params) if params[condition]
end

Re: Refactor a db search based on received params

BTW. I think that the most rude error in your code is using naming on your language.
Imagine that on your project would work chinese, russian, arabic and so on. Would you understand code if it would be on their language?
For example I'll name variable as primer_zadania(it is on russian smile ). So try to use widespread language.
It's an advice. wink

Re: Refactor a db search based on received params

excellent, many thanks.  i will try this out soon.  you are completely correct about language, however this is a small project with no intention of going public, when that time comes i'll stick to english (-: