Rails ActiveRecord: несколько условий в поиске

Это может быть больше синтаксиса Ruby, чем что-либо еще. Мне трудно получить два предельных условия для SomeObject.find going.

Разделенные, условия, похоже, работают:

if search != ''
  find(:all, :conditions => ['name LIKE ?', "%#{search}%"])
else
  find(:all, :conditions => ['active', 1]).shuffle
end

Для первого случая я делаю следующее:

find(:all, :conditions => ['name LIKE ?', "%#{search}%"], ['active', 1])

Но строка бросает syntax error, unexpected ')', expecting tASSOC.

Ответ 1

Рельсы 2

find(:all, :conditions => ['name LIKE ?', "%#{search}%"], ['active', 1]) не является надлежащим синтаксисом для передачи хэшей методу. Вы можете оставить фигурные скобки от хэша, если это последний аргумент метода, но в этом случае вы передаете массив как последний аргумент.

Используйте вместо этого следующее:

find(:all, :conditions => ["name LIKE ? AND active = ?", "%#{search}%", 1])

или

params = {:search => "%#{search}%", :active => 1}
find(:all, :conditions => ["name LIKE :search AND active = :active", params])

Рельсы 3 и 4

Вероятно, вы захотите сделать что-то более похожее на следующие версии Rails:

 scope :active, -> { where(active: true) }
 scope :name_like, ->(search) { where("name LIKE ?", "%#{search}%") }

И тогда вы бы назвали это следующим образом:

YourModel.active.name_like("Bunnies")

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

Если вам не нравится синтаксис scope, вы также можете определить его как методы класса:

def self.active
  where(active: true)
end

def self.name_like(search)
  where("name LIKE ?", "%#{search}%")
end

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

results = active
results = results.name_like(search) if search.present?

Ответ 2

Вместо использования if-else, который будет включать избыточность для проверки на active = 1, более простой синтаксис будет примерно таким:

result = where(:active => 1)
result = result.where('name like ?', "%#{search}%") unless search.blank?

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

Ответ 3

Я думаю, что вы используете рельсы 2

попробуйте это.

find(:all, :conditions => ['name LIKE ? and active = 1', "%#{search}%"])
Синтаксис

rails 3

where('name LIKE ? and active = 1', "%#{search}%")