当用户注册我的应用程序以查看用户名是否已经存在时,我正在进行ajax验证。每当您取消焦点/模糊用户名字段时,就会发出请求。在本地,我使用的是MySQL,在Heroku上是Postgres,所以我认为问题就在那里,因为这在我的开发机器上本地运行得很好。
注册的用户名是Matt,例如。。。
开发:
- Matt=拍摄是真的
- matt=拍摄为真
- MATT=取为真
- MaTt=取值为真,等等
生产:
- Matt=拍摄是真的
- matt=take为false
- MATT=取为假
- MaTt=取值为假
这是一种方法(你甚至可以看到,我更进一步,试图迫使它下降,再次在本地工作,但不是在生产中)。。。
def checkname
scrubb = ActionController::Base.helpers.sanitize(params[:username], :tags => '')
user = User.find_by_username(scrubb, :conditions => [ "lower(username) = ?", scrubb.downcase ])
if user.blank?
render :json => { :isAvailable => true }
else
render :json => { :isAvailable => false }
end
return
end
**编辑**
这是生成的MySQL查询的输出:
SELECT `users`.* FROM `users` WHERE `users`.`username` = 'MATT' AND (lower(username) = 'matt') LIMIT 1
所以,看起来真正的问题是Rails正在生成AND语句。我该如何删除它?
您使用了错误的方法来检查用户名。此:
User.find_by_username(scrubb)
只是生成此SQL:的一种方法
select * from users where username = ...
然后添加一些:conditions
:
:conditions => [ "lower(username) = ?", scrubb.downcase ]
而CCD_ 2只是将它们附加到它通常使用的WHERE子句上。结果是:
User.find_by_username(scrubb, :conditions => ...)
表示:
找到
username
为scrubb
且:conditions
为真的User
。
在MySQL中,字符串比较:
`users`.`username` = 'MATT'
在您的配置中显然不区分大小写(我相信默认配置),但在PostgreSQL中它将区分大小写;如果username
是'Matt'
,那么在PostgreSQL中该条件将失败,并且除了区分大小写的匹配之外,您将找不到任何其他匹配。
不要使用find_by_username
(或者其他任何东西,如果您希望username
不区分大小写),使用where
和count
:
n = User.where('lower(username) = ?', scrubb.downcase).count
或更好的where
和exists?
:
taken = User.where('lower(username) = ?', scrubb.downcase).exists?
在User
中添加一个作用域似乎也是个好主意:
class User < ActiveRecord::Base
def self.with_username(username)
where('lower(username) = ?', username)
end
end
然后你可以说:
how_many = User.with_username(scrubb).count
taken = User.with_username(scrubb).exists?
而且您不必在其他任何地方担心这个不区分大小写的问题。
请在开发和生产中使用相同的堆栈,还有各种其他的小差异会让你感到悲伤。
实际上,我通过自己的更多研究来解决这个问题,这对我来说更有意义。我认为这可能会帮助其他人。
username = params[:username]
username.downcase
@user = User.where(User.arel_table[:username].matches("%#{username}%")).first
使用Arel
和matches
将对Postgres使用ILIKE
运算符,对其他所有内容(源)使用LIKE
运算符。然后,调用find_by_username
0,以便接收用户的单个对象,而不是集合(源)。
在MySQL和Postgres中都能准确地工作。我明白,拥有不同的生产和开发环境是不好的做法。。。故事的寓意。我很快就会着手处理这个问题。
注意:在不区分大小写的主题上,我还遇到了一个非常有用的gem,名为route_downser,您可能对此感兴趣。