Ruby: объединение нормальных и побитовых сравнений - PullRequest
0 голосов
/ 16 ноября 2011

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

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

@users = User.reject{|user| user.first_name !~ /^#{term}/i && user.last_name !~ /^#{term}/i } #Works as expected - returns users matching 'term'

@users = User.reject{|user| user.first_name !~ /^#{term}/i && user.last_name !~ /^#{term}/i && user.suspended? } # Does not work - returns a full list of active users, as well as any suspended users that match.

@users = User.reject{|user| user.first_name !~ /^#{term}/i && user.last_name !~ /^#{term}/i }
@users.reject!{|user| user.suspended?} # This combination works, but I feel like there should be a way to condense it into a single line

Я также пытался добавить несколько скобок вокруг первых двух условий, но это тоже не помогает.

Любая помощь приветствуется

Ответы [ 3 ]

2 голосов
/ 16 ноября 2011

Здесь нет побитовой операции, !~ - это отрицательное совпадение с регулярным выражением (подумайте "не совпадает").

Для вашего фактического вопроса:

@users = User.reject{|user| user.first_name !~ /^#{term}/i && user.last_name !~ /^#{term}/i || user.suspended? }

По сути, это говорит: «отклонить пользователя, если это имя и фамилия не соответствуют предоставленному регулярному выражению или если пользователь приостановлен».Ваша версия работала только для пользователей с недопустимыми именами, которые также были приостановлены (из-за &&).

1 голос
/ 16 ноября 2011

Может помочь, если вы перенесете некоторые из этих условий в именованные области.Кроме того, это переместит ваш поиск в MySQL.Интересно, как это повлияет на производительность?

scope :first_name_not_like, lambda {|term| where(["first_name NOT RLIKE '^#{?}'", term])}
scope :last_name_not_like, lambda {|term| where(["last_name NOT RLIKE '^#{?}'", term])}
scope :not_suspended, lambda { where(["suspended NOT true"])}

Или что-то в этом роде?

Тогда вы можете сделать

@users = User.first_name_not_like(term).last_name_not_like_(term).not_suspended
0 голосов
/ 16 ноября 2011

Я думаю, что ваш окончательный && должен быть ||

@users = User.reject{|user| user.first_name !~ /^#{term}/i && user.last_name !~ /^#{term}/i || user.suspended? }
...