Ruby:结合正常和按位比较

时间:2011-11-16 16:03:27

标签: ruby comparison bit-manipulation

这似乎是一个愚蠢的简单问题。我正在搜索用户列表,使用按位运算符来确定名字和姓氏是否与提供的术语匹配(我没有编写此代码,这是遗留的)。

现在我需要添加第三个条件 - 他们的状态不是'禁用'。没有第三个条件,搜索按预期工作。但是,当我添加另一个和语句时,它会中断。

@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 个答案:

答案 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? }