Rails "validates_uniqueness_of"대소 문자 구분


93

다음은 모델입니다 (SQLLite3 사용 중).

class School < ActiveRecord::Base

  validates_uniqueness_of :name

end

예를 들어 "Yale"을 추가 한 후 "Yale"을 추가 할 수 없지만 "yale"을 추가 할 수 있습니다. 유효성 검사 대소 문자를 구분하지 않으려면 어떻게해야합니까?

편집 : 발견- 활성 레코드 유효성 검사

답변:


232

validates_uniqueness_of :name, :case_sensitive => false트릭을 수행하지만 다중 서버 / 서버 프로세스 (예 : Phusion Passenger, 다중 Mongrel 등 실행) 또는 다중 스레드 서버가있는 경우 고유성을 보장 validates_uniqueness_of하지 않는다는 점을 명심해야 합니다. 다음과 같은 일련의 이벤트를 얻을 수 있기 때문입니다 (순서가 중요합니다).

  1. 프로세스 A는 이름이 'foo'인 새 사용자를 생성하라는 요청을받습니다.
  2. 프로세스 B는 동일한 작업을 수행합니다.
  3. 프로세스 A는 해당 이름이 아직 존재하지 않는지 DB에 요청하여 'foo'의 고유성을 확인합니다.
  4. 프로세스 B는 동일한 작업을 수행하고 동일한 응답을받습니다.
  5. 프로세스 A는 insert새 레코드에 대한 명령문을 제출 하고 성공합니다.
  6. 해당 필드에 대한 고유성을 요구하는 데이터베이스 제약 조건이있는 경우 프로세스 B는 insert새 레코드에 대한 명령문을 제출 하고 SQL 어댑터에서 돌아 오는 추악한 서버 예외로 실패 합니다. 데이터베이스 제약 조건이없는 경우 삽입이 성공하고 이제 이름이 'foo'인 두 행이 있습니다.

validates_uniqueness_ofRails 문서의 "동시성 및 무결성"을 참조하십시오 .

에서 레일 3 판 루비 :

... 이름에도 불구하고 validates_uniqueness_of는 열 값이 고유하다는 것을 보장하지 않습니다. 할 수있는 일은 유효성 검사를 수행 할 때 유효성을 검사하는 레코드의 값과 동일한 값이있는 열이 없는지 확인하는 것뿐입니다. 고유해야하는 열에 대해 동일한 값을 가진 두 레코드가 동시에 생성되고 두 레코드 모두 유효성 검사를 통과 할 수 있습니다. 고유성을 적용하는 가장 신뢰할 수있는 방법은 데이터베이스 수준 제약을 사용하는 것입니다. "

참고 이 프로그래머의 경험 과를 validates_uniqueness_of.

일반적으로 이런 일이 발생하는 한 가지 방법은 새 계정을 만들 때 웹 페이지에서 실수로 이중 제출을하는 것입니다. 사용자가 다시 받게되는 것은 두 번째 (추악한) 오류이고 실제로 성공했을 때 등록이 실패했다고 생각하게 만들기 때문에 해결하기 어려운 문제입니다. 이를 방지하는 가장 좋은 방법은 이중 제출을 방지하기 위해 자바 스크립트를 사용하는 것입니다.


4
참고로 DB 수준 제약 조건을 수정하여이 문제를 해결하기 위해 Rails에 제출 한 패치가 있습니다. rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets/…
Jordan Brough

또한, 사용이의 더 많은 수정이 다년생 문제 "사용자가 더블 버튼 제출을 클릭"하지만 : disable_with
Ghoti

77

Rails 3에서는 모델에서이를 수행 할 수 있습니다.

validates :name, :uniqueness => true

또는 case_sensitivity없이

validates :name, :uniqueness => {:case_sensitive => false}

이것이 바로 내가 원하는 것입니다.
Jigar 밧

1
저는 10 년 넘게 Rails를 해왔습니다. 이 옵션에 대해 배우고 있다는 것이 믿을 수 없습니다. Rails에는 기술 수준에 관계없이 항상 새로운 것을 배울 수 있습니다.
danielricecodes

24

대소 문자를 구분하지 않는 옵션이 있습니다.

  validates_uniqueness_of :name, :case_sensitive => false

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.