ActiveRecord поддерживает динамические условия в операторах sql? - PullRequest
0 голосов
/ 09 июня 2009

Я хочу сделать SQL-запрос в приложении Rails, которое добавляет условие при добавлении раскрывающегося меню. Очевидно, что я не хочу выполнять поиск с пустым условием, если раскрывающийся список не выбран. Как разработать динамическое условие в операторе SQL?

непроверенный пример:

Когда раскрывающийся список не выбран: Object.find ("Билли": условия => {})

Когда выбран раскрывающийся список: Object.find ("Билли": условия => {"last_name =>" Джонсон "})

Спасибо за ваш вклад!

Ответы [ 4 ]

5 голосов
/ 09 июня 2009

Не совсем уверен, что вы делаете, но общий способ достижения этого состоит в том, чтобы значение раскрывающегося списка (не видимый текст) было идентификатором объекта, который вы хотите выбрать. Если у вас нет выбора, вы можете использовать что-то вроде этого:

last_name = unless params[:object][:last_name]

conditions = []
conditions << "last_name = ?" unless last_name.blank?
conditions << last_name unless last_name.blank?

Object.find("billy", :conditions => conditions)

Проверьте эту ссылку , чтобы узнать больше о ActiveRecord::Base.find() методах и правильном способе их использования. Также посмотрите это замечательное руководство , чтобы узнать, как защитить себя от атак SQL-инъекций.

Редактировать 1: Изменен код, чтобы быть чище. Этот метод также имеет преимущество, заключающееся в возможности легко добавлять отдельные условия, просто убедитесь, что вы добавили все «что-то =?» перед добавлением связанного значения (param).

Редактировать 2: Если вы еще не видели помощника по формам select , вы можете использовать его в раскрывающемся списке. Делает жизнь намного проще: -)

3 голосов
/ 09 июня 2009

Предполагая, что ваш #find находится в контроллере и что выбранное значение входит как элемент в params (и я думаю, что вы должны рассмотреть возможность что-то изменить, если нет!), Тогда вы сможете сделать что-то вроде этого:

if params[:last_name] # or whatever it's actually called
  Object.find("billy," :conditions => {'last_name = ?', params[:last_name]})
else
  Object.find("billy")
end

Если вы используете относительно свежую версию ActiveRecord (2.1 должна сделать это, возможно, 2.0), то вы можете сместить эту логику до named_scope:

class Object < ActiveRecord::Base
  named_scope :for_last_name, lambda { |nm| { :conditions => nm.nil? ? {} : { last_name => nm } }

и тогда ваш контроллер сводится к (а мы любим тонкие контроллеры)

Object.for_last_name(params[:last_name])

(все несколько непроверено)

1 голос
/ 09 июня 2009

Может быть, это?

Object.find("billy", :conditions => last_name.nil? ? {} : {:last_name => last_name})
0 голосов
/ 23 июля 2010

Я использую SmartTuple для этого. Это просто, но предлагает системный подход к построению «условных условий».

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...