I have solved the problem of searching my child records.
I wrote a custom search method for meta_search:
scope :with_name_and_value_range,lambda {|name, low, high|
joins(:analytical_results).where(['analytical_results.name = ?', name]).with_low(low).with_high(high) }
scope :with_name,lambda {|name|
joins(:analytical_results).where(['analytical_results.name = ?', name])}
scope :with_low,lambda {|low|
joins(:analytical_results).where(['analytical_results.value >= ?', low]) unless low.blank?}
scope :with_high,lambda {|high|
joins(:analytical_results).where(['analytical_results.value <= ?', high]) unless high.blank?}
search_methods :with_name_and_value_range,
:splat_param => true, :type => [:string, :string, :string]
Then in my view I had:
-if @analytical_results.present?
%h4.search
Analytical Results
%dl.search
- count = 1
-@analytical_results.each do |result|
%dt
= f.label :with_name_and_value_range, result.name
%dd
= f.multiparameter_field :with_name_and_value_range,
{:field_type => :hidden_field, :value => "#{result.name}", :id => "search_with_name_and_value_range(#{count})", :name => "search[with_name_and_value_range(#{count})]"},
{:field_type => :text_field, :placeholder => "from", :class => "small_field",:id => "search_with_name_and_value_range(#{count + 1})",:value => params[:search]["with_name_and_value_range(#{count +1})"],:name => "search[with_name_and_value_range(#{count + 1})]"},
{:field_type => :text_field, :placeholder => "to", :class => "small_field",:value => params[:search]["with_name_and_value_range(#{count +2})"],:id => "search_with_name_and_value_range(#{count + 2})", :name => "search[with_name_and_value_range(#{count + 2})]"}
- count += 3
This would create a label, a hidden_field for the name, and a low and high value text field. With a single type of analytical result present this worked like a charm. An array of three values would be passed to the lambda block and evaluated in my custom search method.
BUT:
With additional analytical_results type present, the array became longer by three values for each type, e.g. for two :
[type1, low1, high1, type2,low2,high2]
So I got an error that I did provide 6 parameters when only 3 where allowed.
I could not be bothered to rewrite the meta_search gem so I created a work around in my workingwell controller. Basically I check the params[:search] hash if it contains any keys where the name contains "with_name_and_value_range" indicating my custom search method. I extract the key value pairs from the params[:search] hash into a new hash called "new" and delete the key value pairs from the params[:search] hash so they do not become evaluated when calling
I initialize the search instance variable with all activewells. In case the new hash does exist and is longer than 0 I slice it by 3 into single value triplets (name, low,high). I loop over them and use them to restrict the @search variable. I merge the new and params[:search] hash so I can initialize the search form once the search is submitted with the values for my custom search method fields.
Works like a charm...
def index
@analytical_results = AnalyticalResult.select(:name).uniq if AnalyticalResult.all.length > 0
new = {} # instantiate a new has to hold extra values
if params[:search].present?
params[:search].each do |key, value| # loop over the params[:search] hash
if key.include? "with_name_and_value_range" # check if the key contains "with_name_and_value_range"
new[key] = value # if yes add the new key-value pair to the new hash
params[:search].delete(key) # remove the key-value pair from the params[:search] hash
end
end
else
params[:search] = {}
end
@search = Workingwell.where("workingwells.name != ? AND workingwells.name != ?", "PBS", "empty")
if new.length > 0
new_a = new.to_a.each_slice(3).to_a # convert new has into an 2d array
count = 0
while count < new_a.length
if new_a[count][1][1] != ""
@search = @search.joins(:analytical_results).where("analytical_results.name = ? AND analytical_results.value >= ?", "#{new_a[count][0][1]}", "#{new_a[count][1][1]}")
end
if new_a[count][2][1] != ""
@search = @search.joins(:analytical_results).where("analytical_results.name = ? AND analytical_results.value <= ?", "#{new_a[count][0][1]}", "#{new_a[count][2][1]}")
end
count += 1
end
end
@search = @search.search(params[:search])
if new.length > 0
params[:search] = params[:search].merge(new)
end
@workingwells = @search.paginate(:page => params[:page])
end
Last edited by helmerj (2012-07-02 15:25:36)