1

ユーザーがアプリケーションにサインアップして、ユーザー名が既に存在するかどうかを確認するときに、ajax 検証を行っています。ユーザー名フィールドのフォーカスを外したりぼかしたりするたびに、リクエストが行われます。ローカルでは MySQL を使用しており、Heroku では Postgres を使用しているため、開発マシンでローカルに完全に機能するため、問題が何らかの形でそこにあると想定しています。

登録されたユーザー名は、たとえばマットです...

発達:

  • マット=撮影は真です
  • マット = 撮影は真です
  • MATT = 撮影は true
  • MaTt = 取得は true など...

製造:

  • マット=撮影は真です
  • マット = 撮影は false
  • MATT = 撮影は false
  • MaTt = 取得は false

そして、ここにその方法があります(さらに一歩進んでダウンケースを強制しようとしたこともわかりますが、ローカルでは正常に機能しますが、本番環境では機能しません)...

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 ステートメントにあるようです。どうすればそれを削除できますか?

4

2 に答える 2

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 => ...)

意味:

Userusernamescrubb、どこ:conditionsが真であるかを見つけます。

MySQL では、文字列比較:

`users`.`username` = 'MATT'

あなたの設定では大文字と小文字が区別されないようです(デフォルトの設定だと思います)が、PostgreSQLでは大文字と小文字が区別されます。usernameがの場合、'Matt'その条件は PostgreSQL で失敗し、大文字と小文字を区別する一致以外は何も見つかりません。

これには使用しないでください(大文字と小文字を区別しない場合find_by_usernameは他のものにも使用します)。 and を使用します。usernamewherecount

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?

大文字と小文字を区別しないこの問題について、他の場所で心配する必要はありません。

そして、開発と本番で同じスタックを使用してください。他にもあらゆる種類の小さな違いがあり、あなたを悲しませます。

于 2013-08-24T23:46:29.700 に答える