2013-12-12 2 views
0

Я создаю приложение базы данных, которое отслеживает множество данных для Лица, таких как first_name, last_name, DOB и еще 20 полей.Мне нужна форма поиска с большим количеством полей. Как это сделать в Ruby on Rails?

Пользователи должны будут иметь возможность искать все эти поля. У меня возникли проблемы с написанием чистого кода для этого. Приведенный ниже код является то, что я до сих пор в моем people_controller:

данные передаются от form_tag

def search 
    @people = Person.all 
    general_info_string = String.new 

    if(params[:first_name] != "") then general_info_string << 'people.first_name = "' + params[:first_name] + '" AND ' end 
    if(params[:last_name] != "") then general_info_string << "people.last_name = '" + params[:last_name] + "' AND " end 
    ... Lots more of similar clauses 

    general_info_string = general_info_string[0, general_info_string.length - 5] 
     # ^This line removes the trailing " AND " from the string 
    @people = @people.where(general_info_string) 
end 

general_info_string так называется, потому что есть больше «где» подпункты (не показаны) и отдельные строки что я строю для их поиска.

Проблема в том, что код выглядит как беспорядок и кажется «хакерским» способом сделать что-то, что должно хорошо поддерживаться Rails. Как я могу выполнить эту операцию более чистым способом?

ответ

1

Это не просто хакки - это дает вам возможность открывать атаку с применением струн.

Вам нужен :conditions с помощью ? шаблона, как в этом примере:

:conditions => ["key1 = ?", var] 

но вы должны сделать часть шаблона в строку, которая растет один раз в параметре, и вам нужно сделать вар в массив, который растет с каждым значением параметра. Это дает вам что-то вроде этого:

template = [] 
values = [] 

if params[:first_name].present? 
    template.push 'people.first_name = ?' 
    values.push params[:first_name] 
end 

if params[:last_name].present? 
    template.push 'people.last_name = ?' 
    values.push params[:last_name] 
end 

template = template.join(' AND ') 
:conditions => [template, *values] 

Оттуда, вы должны высыхать все эти сослагательное наклонение, например, с помощью таблицы ключей значений. Затем вы зацикливаете стол, проверяете ключ и нажимаете его результаты в массивы:

fields = [:first_name, :last_name, :shoe_size, ...] 

fields.each do |field| 
    if params[field].present? 
     template.push "people.#{field} = ?" 
     values.push params[field] 
    end 
end 
+0

Можете ли вы объяснить свой последний абзац дальше? Как создать «таблицу значений ключей»? – user1943735

Смежные вопросы