실제 레코드가 열이 아니라 고유한지 확인하는 레일 웨이 방법이 있습니까? 예를 들어, 우정 모델 / 테이블은 다음과 같은 여러 개의 동일한 레코드를 가질 수 없습니다.
user_id: 10 | friend_id: 20
user_id: 10 | friend_id: 20
답변
validates_uniqueness_of
다음과 같이 통화 범위를 지정할 수 있습니다 .
validates_uniqueness_of :user_id, :scope => :friend_id
답변
하나의 열 validates
에서 유효성을 검사 하는 데 사용할 수 있습니다 uniqueness
.
validates :user_id, uniqueness: {scope: :friend_id}
여러 열에 대한 유효성 검사 구문은 비슷하지만 대신 필드 배열을 제공해야합니다.
validates :attr, uniqueness: {scope: [:attr1, ... , :attrn]}
그러나 위에 표시된 유효성 검사 방식에는 경쟁 조건이 있으며 일관성을 보장 할 수 없습니다. 다음 예제를 고려하십시오.
-
데이터베이스 테이블 레코드는 n 개의 필드 로 고유해야 합니다.
-
각각 별도의 프로세스 ( 응용 프로그램 서버, 백그라운드 작업자 서버 또는 사용중인 것 )에 의해 처리되는 여러 ( 2 개 이상의 ) 동시 요청, 데이터베이스에 액세스 하여 테이블에 동일한 레코드를 삽입합니다.
-
병렬로 각 프로세스는 동일한 n 필드를 가진 레코드가 있는지 검증 합니다.
-
각 요청에 대한 유효성 검사가 성공적으로 통과되고 각 프로세스는 동일한 데이터를 사용하여 테이블에 레코드를 만듭니다.
이러한 종류의 동작을 피하려면 db 테이블에 고유 제한 조건 을 추가해야 합니다. 당신은 그것을 설정할 수 있습니다add_index
다음 마이그레이션을 실행하여 하나 이상의 필드에 도우미로 .
class AddUniqueConstraints < ActiveRecord::Migration
def change
add_index :table_name, [:field1, ... , :fieldn], unique: true
end
end
주의 사항 : 고유 한 제약 조건을 설정 한 후에도 두 개 이상의 동시 요청이 동일한 데이터를 db에 쓰려고 시도하지만 중복 레코드를 만드는 대신 ActiveRecord::RecordNotUnique
예외 가 발생 하여 별도로 처리해야합니다.
begin
# writing to database
rescue ActiveRecord::RecordNotUnique => e
# handling the case when record already exists
end
답변
이는 두 열에 대한 데이터베이스 제약 조건으로 수행 할 수 있습니다.
add_index :friendships, [:user_id, :friend_id], unique: true
레일스 유효성 검사기를 사용할 수 있지만 일반적으로 데이터베이스 제약 조건을 사용하는 것이 좋습니다.
더 읽기 : https://robots.thoughtbot.com/validation-database-constraint-or-both