这似乎是一个愚蠢的简单问题。我正在搜索用户列表,使用按位运算符来确定名字和姓氏是否与提供的术语匹配(我没有编写此代码,这是遗留的)。
现在我需要添加第三个条件 - 他们的状态不是'禁用'。没有第三个条件,搜索按预期工作。但是,当我添加另一个和语句时,它会中断。
@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
我也尝试在前两个条件中添加一些括号,但这也无济于事。
感谢任何帮助
答案 0 :(得分:2)
这里没有按位操作,!~
是一个否定的正则表达式匹配(认为“不匹配”)。
对于您的实际问题:
@users = User.reject{|user| user.first_name !~ /^#{term}/i && user.last_name !~ /^#{term}/i || user.suspended? }
基本上这表示:'如果first_name和last_name与提供的正则表达式不匹配或者用户被挂起,则拒绝用户'。您的版本仅适用于具有无效名称的用户(因为&&
)。
答案 1 :(得分:1)
如果将其中一些条件移动到命名范围中,它可能会有所帮助。此外,这将使您的搜索进入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
答案 2 :(得分:0)
我认为您的最终&&
应为||
@users = User.reject{|user| user.first_name !~ /^#{term}/i && user.last_name !~ /^#{term}/i || user.suspended? }