2013-01-24 2 views
2

예외가 발생했으며 그 이유를 알고 싶습니다. 누구나 테스트 할 수 있도록 git repo를 만들었습니다. 유증가 설치와ActiveRecord :: RecordNotUnique가 등록에서 발생했습니다. # 왜 생성합니까?

레일 애플 리케이션은 신선합니다. 나는이 예외가 아닌 검증 오류가 발생하는 이유

An ActiveRecord::RecordNotUnique occurred in registrations#create: 

Mysql2::Error: Duplicate entry '[email protected]' for key 'index_users_on_email': INSERT INTO `users` (`authentication_token`, `confirmation_sent_at`, `confirmation_token`, `confirmed_at`, `created_at`, `current_sign_in_at`, `current_sign_in_ip`, `email`, `encrypted_password`, `failed_attempts`, `last_sign_in_at`, `last_sign_in_ip`, `locked_at`, `remember_created_at`, `reset_password_sent_at`, `reset_password_token`, `sign_in_count`, `unconfirmed_email`, `unlock_token`, `updated_at`) VALUES (NULL, '2013-01-24 16:48:23', 'GQwbJzsawxRsbvhp1LkR', NULL, '2013-01-24 16:48:23', NULL, NULL, '[email protected]', '$2a$10$koMNiiZQuhkeWhmYV8PtcOUlvi6rZHTKMs82MGWNa2M/GsUQ0cIHO', 0, NULL, NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL, '2013-01-24 16:48:23') 
activerecord (3.2.11) lib/active_record/connection_adapters/abstract_mysql_adapter.rb:245:in `query' 

:

1000.times do 
    fork do 
    `curl -d "user[email][email protected]&user[password]=pwd&user[password_confirmation]=pwd" localhost:3000/users` 
    end 
end 

내가 후속 예외를 얻을 : 응용 프로그램과 동일한 사용자를 만들려고이 스크립트를 실행

? "http : // localhost : 3000/users/sign_up"웹 페이지에서 이미 사용 된 전자 메일을 사용하여 사용자를 만들려고하면 예외가 발생하지만 유효성 검사 오류가 발생합니다.

포크없이 스크립트 (요청 순차적입니다), 나는 아무런 오류가 발생합니다.

경쟁 조건 문제가있는 것 같습니다.

+0

사용자 이메일은 고유해야합니다. https://github.com/pioz/test_duplicate_entry/blob/master/db/schema.rb#L41 – Ken

+0

git repo https://github.com/pioz/test_duplicate_entry – Pioz

+0

유효성 검사는 Devise gem에 포함되어 있습니다. – Pioz

답변

4

스크립트에서 "[email protected]"이라는 이메일을 사용하여 1000 명의 사용자를 모두 생성하십시오. 사용자 이메일 색인에 고유성 제약이 있습니다 (이메일 주소 당 한 명의 사용자 만 필요함). 이 이메일을 사용하여 두 번째로 사용자를 만들려고하면 오류가 발생합니다.

요청을 포기할 때 동일한 전자 메일을 가진 다른 레코드를 쿼리하기 때문에 devise가 제공 한 validates_uniqueness_of 유효성 검사가 성공할 수 있습니다. 그러나 기록이 실제로 기록 될 때까지 다른 기록이 존재할 수 있습니다. 예를 들어

,

  1. 요청 이메일 기존 1 개 검사 "[email protected]"- 오케이
  2. 요청 이메일 기존 2 개 검사 "[email protected]"- 오케이
  3. 요청 1은 "[email protected]"전자 메일로 레코드를 씁니다. - 괜찮습니다.
  4. 요청 2는 "[email protected]"이라는 전자 메일과 함께 고유성 위반을 기록합니다.
+0

그래,이 예외를 피할 수 있을까? – Pioz

+0

정말로 중요한지는 모르겠지만 정말 중요합니다. 같은 이메일 주소로 동시에 등록하는 두 명의 사용자가 생산 될 가능성은? 그럴 가능성이없는 이벤트를 코딩하기 위해 많은 시간을 보내고 싶습니까? 문제가 발생하면 충분한 오류 메시지가 표시되며 가장 중요한 것은 여전히 ​​고유 한 전자 메일 주소가 있다는 것입니다. – Shadwell

-2

Devise는 이메일을 사용자의 고유 식별자로 사용합니다. 모든 사용자에게 동일한 이메일을 지정할 수 없습니다. 당신이 당신의 스크립트에서하려고 노력 무엇

아니면 새로운 사람을 만드는 대신 사용자를 업데이트하는 것입니다?

+0

아니요, 같은 것을 만들려고합니다. 사용자,하지만 왜 유효성 검사 오류 대신 해당 예외가 있습니까? – Pioz

+0

파티에 늦게 올 경우 승격 조건이 유효성 검사 오류가 아니기 때문에 예외가 발생합니다. '작성!'하면 유효성 검사 오류가 발생하며 'first_or_create'내에서 경쟁 상태가 발생했습니다. – Leito

0

는 글쎄 예외는 인덱스 고유성 제약 조건을 위반하고, 말한다처럼. Devise 생성기를 실행하면 테스트 응용 프로그램에서 db/migrate에있는 유일한 생성기가 생성됩니다. 이 마이 그 레이션에서 당신은 이것을 가지고 :

add_index :users, :email,    :unique => true 

이것은 동일한 이메일로 1000 개의 레코드를 만들려고 할 때 스크립트가 실패하게 만드는 이유입니다. 고유 한 메일을 각 시간을 얻을 수 있도록 우선 들어

, 나는 이런 식으로 뭔가에 샘플 스크립트를 변경할 것 :

1000.times do |i| 
    fork do 
    `curl -d "user[email]=your#{i}@mail.com&user[password]=pwd&user[password_confirmation]=pwd" localhost:3000/users` 
    end 
end 

무엇을 당신이하려는 것은 씨앗이 가짜로 개발 데이터베이스 인 경우 사용자는 database populationseed data에 가로장을 체크 아웃하십시오.

+0

동일한 사용자를 만들지 만 왜 유효성 검사 오류 대신 예외가 발생합니까? – Pioz

+1

Simple : 모델에 이러한 유효성 검사가 없기 때문에 가능합니다. 'user.rb'에'validates : email, uniqueness : true'가 있어야합니다. 내가 이해하지 못하는 것은 같은 사용자에게 1000 번을 생성하려고하는 이유입니다. ??? – HargrimmTheBleak

+0

"http : // localhost : 3000/users/sign_up"웹 페이지에서 이미 사용 된 전자 메일을 사용하여 사용자를 만들려고하면이 예외가 있지만 유효성 검사 오류가 발생하지 않습니다 ... 전자 메일 필드의 유효성 검사 Devise gem에 있습니다. – Pioz