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

Это может быть больше синтаксиса Ruby, чем что-либо еще. У меня возникли трудности с получением двух ограничивающих условий на SomeObject.найти собирается.

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

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.

4 ответов


рельсы 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

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

 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?

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

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

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


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

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

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

rails 3 синтаксис

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

для Rails 4, в rails new find_by и find_by! методы вводятся

читать ответ