Rails + Postgres에서 빈 값을 건너뛰는 고유 인덱스를 만드는 방법은 무엇입니까?
문제
초대 코드를 전송하여 사람들을 조직으로 초대하는 애플리케이션이 있다고 가정해 보겠습니다. 이들은 모든 조직에 대해 고유해야 하며 아직 생성하지 않은 경우 비어 있어야 합니다.
이를 위해
invitation_code
필드를 사용하여 조직 모델 및 마이그레이션을 생성해 보겠습니다.class CreateOrganizations < ActiveRecord::Migration[7.0]
def change
create_table :organizations do |t|
t.string :invitation_code, null: true
end
end
end
시작하기에 좋습니다. 이제
invitation_code
에 대한 고유 인덱스를 생성해 보겠습니다.add_index :organizations, :invitation_code, unique: true
그리고 모델에 유효성 검사를 추가합니다.
validates :invitation_code, uniqueness: true
자, 결과를 보자:
# for non-empty invitation_code
irb(main):004:0> org = Organization.create(invitation_code: "f00b4r")
=> #<Organization id: "a8dc7fd8-7724-445c-bed4-72c94af99151", invitation_code: "f00b4r">
irb(main):005:0> org = Organization.create(invitation_code: "f00b4r")
=> #<Organization id: nil, invitation_code: "f00b4r">
irb(main):006:0> org.errors.messages
=> {:invitation_code=>["has already been taken"]}
비어 있지 않은 값에는 고유하지만 비어 있습니까?
# for empty invitation_code
irb(main):001:0> Organization.create()
=> #<Organization id: nil, invitation_code: nil>
irb(main):002:0> org = Organization.create()
=> #<Organization:0x0000ffff897f2a40 id: nil, invitation_code: nil>
irb(main):003:0> org.errors.messages
=> {:invitation_code=>["has already been taken"]}
음... 마이그레이션에서
invitation_code
가 null이 되도록 허용하므로 새 레코드를 만들 때 db 오류가 발생합니다. 이를 위해서는 마이그레이션을 수정해야 합니다.해결책
인덱스 생성 및 모델 유효성 검사를 수정해야 합니다.
먼저 마이그레이션에 초점을 맞추겠습니다. null이 아닌 값의 범위에서 고유하도록 where 문으로 인덱스를 생성하는 것만 변경해야 합니다.
add_index :organizations, :invitation_code,
unique: true,
where: 'invitation_code IS NOT NULL',
name: 'unique_not_null_invitation_code'
좋아, 우리는 모두 db로 설정되었습니다. 이제 레일 모델:
validates :invitation_code, uniqueness: { allow_blank: true }
그리고 모든 것이 설정되었습니다. 🎉
테스트
마이그레이션을 실행하고 콘솔에서 코드를 빠르게 테스트해 보겠습니다.
# for empty invitation_code
irb(main):001:0> Organization.create()
=> #<Organization id: "88174146-19c6-40e6-b675-ea04c3e4238f", invitation_code: nil>
irb(main):002:0> Organization.create()
=> #<Organization id: "61d630d1-d244-47e4-af46-880a021a26ca", invitation_code: nil>
좋습니다. null
invitation_code
로 생성된 두 개의 조직입니다. 이제 비어 있지 않은 코드로 시도하십시오.# for non-empty invitation_code
irb(main):003:0> Organization.create(invitation_code: "f00b4r")
=> #<Organization id: "8b2ed6e7-76db-4f76-9288-69267ebca5f7", invitation_code: "f00b4r">
irb(main):004:0> org=Organization.create(invitation_code: "f00b4r")
=> #<Organization id: nil, invitation_code: "f00b4r">
irb(main):005:0> org.errors.messages
=> {:invitation_code=>["has already been taken"]}
매력처럼 작동합니다. 행복한 해킹! 🧑💻
Reference
이 문제에 관하여(Rails + Postgres에서 빈 값을 건너뛰는 고유 인덱스를 만드는 방법은 무엇입니까?), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/jedrzejurbanski/how-to-create-unique-field-only-if-not-empty-for-rails-7-and-postgres-2i8g텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)