我以前使用where(username: usernames)
获取一组用户名,并返回一个ActiveRecord :: Users用户。我已经创建了一个较低的(用户名)索引,并用以下内容替换了User#find_by_username:
def self.find_by_username(username)
where("lower(username) = ?", username.downcase).first
end
这失败了:
def self.find_by_usernames(usernames)
where("lower(username) = ?", usernames.map(&:downcase))
end
当它是一个用户名的数组时,它可以工作,但不适用于多个用户名。它生成类似"SELECT \"users\".* FROM \"users\" WHERE (lower(username) = 'joshsmith','vendiddy')"
答案 0 :(得分:3)
更新您的方法如下:
def self.find_by_usernames(usernames)
where("lower(username) in (?)", usernames.map(&:downcase))
end
使用in
代替=
,因为您要检查数组中的多个值。
答案 1 :(得分:0)
默认情况下,某些数据库在文本比较时没有区分大小写,例如MySQL。
where("username in (?)", usernames.map(&:downcase))
除非已覆盖默认值,否则上述内容会在MySQL上提供所需的结果。见this post on Stackoverflow
我同意,除非您希望获得较小的速度优势,否则添加较低的函数应该是首选方法,因为数据库服务器不必首先转换字符串。
> Contact.first
Contact Load (172.3ms) SELECT `contacts`.* FROM `contacts` ORDER BY `contacts`.`id` ASC LIMIT 1
=> #<Contact id: 1, name: "John">
> Contact.where(name: "john")
Contact Load (171.9ms) SELECT `contacts`.* FROM `contacts` WHERE `contacts`.`name` = 'john'
=> #<ActiveRecord::Relation [#<Contact id: 1, name: "John"]>
> Contact.where(name: "JOHN")
Contact Load (172.3ms) SELECT `contacts`.* FROM `contacts` WHERE `contacts`.`name` = 'JOHN'
=> #<ActiveRecord::Relation [#<Contact id: 1, name: "John"]>