当用户注册我的应用程序以查看用户名是否已存在时,我正在进行ajax验证。每当您取消焦点/模糊用户名字段时,都会发出请求。本地我使用MySQL和Heroku它是Postgres,所以我假设问题存在于那里,因为它在我的开发机器上完全本地运行。
注册的用户名为 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
因此,看起来真正的问题是AND语句Rails正在生成。我该如何删除它?
答案 0 :(得分:1)
您使用了错误的方法来检查用户名。这样:
User.find_by_username(scrubb)
只是一种产生这种SQL的方法:
select * from users where username = ...
然后添加一些:conditions
:
:conditions => [ "lower(username) = ?", scrubb.downcase ]
和find_by_username
只是将它们添加到通常使用的WHERE子句中。结果是:
User.find_by_username(scrubb, :conditions => ...)
表示:
找到
User
为username
且scrubb
为真的:conditions
。
在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?
并且你不必担心其他任何地方的这种不区分大小写的问题。
请在开发和制作中使用相同的堆栈,还有各种其他的小差异会让你感到悲伤。
答案 1 :(得分:0)
我实际上通过自己的一些研究来解决这个问题,这对我来说更有意义。认为它可能会帮助其他人。
username = params[:username]
username.downcase
@user = User.where(User.arel_table[:username].matches("%#{username}%")).first
使用Arel
和matches
将ILIKE
运算符用于Postgres,LIKE
用于其他所有运算符(source)。然后,调用first
,以便您收到用户的单个对象而不是集合(source)。
完全适用于MySQL和Postgres中的应用方式。我理解,拥有不同的生产和开发环境是不好的做法...... moral of the story。我很快就会解决这个问题。
注意:关于不区分大小写的主题,我还遇到了一个非常有用的宝石,名为route_downcaser,您可能会感兴趣。