Search code examples
ruby-on-railsrubyruby-on-rails-2

How can i simplify conditions when i have much params in my search?


For example

I have 5 params in my search view:

  params[:a]       params[:b]       params[:c]       params[:d]       params[:e]

And I want to search in my controller when:

  params[:a].present? and params[:b].nil?
  params[:a].present? and params[:c].nil?
  params[:a].present? and params[:e].nil?
  params[:b].present? and params[:c].nil?
  params[:b].present? and params[:d].nil?
   ............
  params[:a].nil? and params[:b].nil?
  .............

Here is what I tried:

 controller: 

 if params[:a].nil?
    @query
 else
    if params[b].nil?
      @another_query
    else
      ...........#and it will continue with lots of conditions according with params
    end
 end

Well there are lots of conditions that I can try

Here is using a real example I got this error "undefined method `paginate' for nil:NilClass"

 #table
 policies
   id   num_policy   type_id    doc    name
    1        2323      1       181844  Charles
    2        2121      2       151511  Aguardientico
    3        3423      2       434344  Benjamin

 #controller

if params[:num_policy].present?
  @search= Policy.find(:all,:conditions=>['num_policy LIKE ?',params[:num_policy] ])
end

if params[:type_id].present?
  @search= Policy.find(:all,:conditions=>['type_id LIKE ?',params[:type_id] ])
end

if params[:doc].present?
  @search= Policy.find(:all,:conditions=>['doc LIKE ?',params[:doc] ])
end

if params[:name].present?
  @search= Policy.find(:all,:conditions=>['name LIKE ?',params[:name] ])
end

if params[:doc].present? and params[:type_id].present?
  @search= Policy.find(:all,:conditions=>['doc LIKE ? and type_id LIKE ?',params[:doc],params[:type_id] ])
end

@policies= @search.paginate( :page => params[:page], :per_page =>2)

#view

<% form_tag :controller=>"policy",:action=>"search" do %>
   <%= text_field_tag "num_policy",params[:num_policy] %>
   <%= text_field_tag "doc",params[:doc] %
   <%= text_field_tag "name",params[:name] %
   <%= text_field_tag "type_id",params[:type_id] %
<% end %> 

 <% @policies.each do |p| %>
   <%= p.num_policy %>
   <%= p.type_id %>
   <%= p.doc %>
   <%= p.name %>
 <% end %>

But if remove paginate I got this error "You have a nil object when you didn't expect it! You might have expected an instance of Array. The error occurred while evaluating nil.each"

 #controller
 @policies= @search

 #says that my line  <% @policies.each do |p| %>  is nil

Is there any way to control them?

Please i just want opinions maybe someone happened it too..

Thanks.


Solution

  • @search = Policy.scoped
    @search = @search.where('num_policy LIKE ?', params[:num_policy]) if params[:num_policy].present?
    @search = @search.where('type_id LIKE ?', params[:type_id]) if params[:type_id].present?
    @search = @search.where('doc LIKE ?', params[:doc]) if params[:doc].present?
    @search = @search.where('name LIKE ?', params[:name]) if params[:name].present?
    @policies = @search.paginate(page: params[:page], per_page: 2)
    

    BTW: The issue is because you are creating @search inside the if statements so if no params exists then @search does not exists.

    This is the rails 2 version:

    conditions_str = []
    conditions_values = {}
    ['num_policy', 'type_id', 'doc', 'name'].each do |cond|
      if params[cond.to_sym].present?
        conditions_str << "#{cond} LIKE :#{cond}"
        conditions_values[cond.to_sym] = params[cond.to_sym]
      end
    end
    @policies = Policy.find(:all, :conditions => [conditions_str.join(" AND "), conditions_values])