Рельсы находят: условия - PullRequest
1 голос
/ 05 мая 2010

У меня есть модель Reservation, которую я ищу с тремя полями. container_id всегда должно быть self.id, но как confirmed и auto_confirmed только один должен быть истинным. У меня есть следующее, но оно не выполняет то, что мне нужно:

Reservation.find(:all, 
:conditions => ['container_id = ? AND confirmed = ? OR auto_confirm = ?', 
self.id, true, true,])

Как мне это изменить?

Ответы [ 5 ]

6 голосов
/ 05 мая 2010

Я не уверен, что у меня возникла ваша проблема, но насколько я понимаю, это сработает:

Reservation.find(:all, 
:conditions => ['container_id = ? AND (confirmed = ? OR auto_confirm = ?)', 
self.id, true, true,])
3 голосов
/ 05 мая 2010

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

Reservation.find(:all, 
                 :conditions => ['container_id = :container AND 
                  ( (confirmed = :flag and auto_confirm != :flag) ||
                    (confirmed != :flag and auto_confirm = :flag))', 
                    {:container=> self.id, :flag=>true}]
               )
0 голосов
/ 05 мая 2010

То, что вы говорите, не соответствует действительности - запрос типа

  SELECT * FROM foos WHERE content_id = 345 AND (confirm = 1 OR auto_confirm = 1)

выберет строки, в которых оба столбца «подтверждения» установлены в 1 (а ActiveRecord создает столбцы tinyint для логических значений и проверяет значения 1 и 0).

Если вы имеете в виду "найти все строки, совпадающие по content_id и имеющие подтверждение EITHER ИЛИ auto_confirmed true, но НЕ оба" , то вы переходите к запросу, подобному этому

 SELECT * FROM foos WHERE content_id = 345 AND ((confirmed = 1 AND auto_confirm = 0) OR (confirmed = 0 AND auto_confirm = 1))

который вы перефразируете в терминах AR, подобных этому

  Reservation.find(:all, 
    :conditions => [
      'container_id = ? AND ((confirmed = 1 AND auto_confirm != 1) OR (confirmed = 0 AND auto_confirm != 1))', 
      self]
  )

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

0 голосов
/ 05 мая 2010

Я не уверен, не зависит ли это от базы данных, но вы можете попробовать

Reservation.find(:all, 
:conditions => ['container_id = ? AND confirmed = ? **XOR** auto_confirm = ?', 
self.id, true, true,])
0 голосов
/ 05 мая 2010

Я думаю что-то вроде этого:

Reservation.find(:all, 
:conditions => ['container_id = ? AND ((confirmed != true AND auto_confirm = true) OR (confirmed = true AND auto_confirm != true))', 
self.id])
...