programing

레일즈 마이그레이션에서 검사 제약 조건을 추가하려면 어떻게 해야 합니까?

stoneblock 2023. 7. 28. 21:45

레일즈 마이그레이션에서 검사 제약 조건을 추가하려면 어떻게 해야 합니까?

레일즈 앱의 기존 테이블에 새 정수 열을 추가해야 합니다.열은 값 1, 2, 3만 가질 수 있으므로 표/열에 체크 제약 조건을 추가하려고 합니다.레일즈 마이그레이션 내에서 이 제약 조건을 지정하려면 어떻게 해야 합니까?

레일즈 마이그레이션은 제약 조건을 추가하는 어떤 방법도 제공하지 않지만 마이그레이션을 통해 수행할 수 있지만 실제 SQL을 전달하여 실행()할 수 있습니다.

마이그레이션 파일 만들기:

ruby script/generate Migration AddConstraint

이제 마이그레이션 파일에서 다음을 수행합니다.

class AddConstraint < ActiveRecord::Migration
  def self.up
    execute "ALTER TABLE table_name ADD CONSTRAINT check_constraint_name CHECK (check_column_name IN (1, 2, 3) )"
  end

  def self.down
    execute "ALTER TABLE table_name DROP CONSTRAINT check_constraint_name"
  end
end

레일 6.1+ 구속조건 확인

Rails 6.1은 데이터베이스 마이그레이션에 검사 제약 조건에 대한 기본 지원을 추가했습니다.

이제 정수 열 값을 1, 2, 3으로 제한하는 검사 제약 조건을 추가하기 위한 마이그레이션을 다음과 같이 작성할 수 있습니다.

class AddConstraint < ActiveRecord::Migration
  def up
    add_check_constraint :table_name, 'check_column_name IN (1, 2, 3)', name: 'check_constraint_name'
  end

  def down
    remove_check_constraint :table_name, name: 'check_constraint_name'
  end
end

여기 및 에 대한 자세한 내용을 확인할 수 있는 상대 PR 링크가 있습니다.

마이그레이션 검증자 보석으로 이 작업을 수행할 수 있습니다.자세한 내용은 여기를 참조하십시오. https://github.com/vprokopchuk256/mv-core

이 보석을 사용하면 DB 수준에서 포함 검증을 정의할 수 있습니다.

def change
  change_table :table_name do |t|
    t.integer :column_name, inclusion: [1, 2, 3]
  end
end

또한 유효성 검사를 정의하는 방법과 표시해야 하는 오류 메시지를 정의할 수 있습니다.

def change
  change_table :posts do |t|
    t.integer :priority, 
              inclusion: { in: [1, 2, 3], 
                           as: :trigger, 
                           message: "can't be anything else than 1, 2, or 3" }
  end
end

마이그레이션에서 모델로 바로 검증 수준을 높일 수도 있습니다.

class Post < ActiveRecord::Base 
  enforce_migration_validations
end

마이그레이션에서 정의된 검증은 모델의 ActiveModel 검증으로도 정의됩니다.

Post.new(priority: 3).valid? 
=> true

Post.new(priority: 4).valid?
=> false

Post.new(priority: 4).errors.full_messages
=> ["Priority can't be anything else than 1, 2, or 3"]

이 답변은 2021년 5월부터 사용되지 않습니다.

나는 방금 이것에 대한 보석을 출판했습니다: active_record-postgres-constraints.README에서 설명하는 것처럼 db/schema.rb 파일과 함께 사용할 수 있으며 마이그레이션에서 다음 방법을 지원합니다.

create_table TABLE_NAME do |t|
  # Add columns
  t.check_constraint conditions
  # conditions can be a String, Array or Hash
end

add_check_constraint TABLE_NAME, conditions
remove_check_constraint TABLE_NAME, CONSTRAINT_NAME

현재 포스트그레스만 지원됩니다.

저는 방금 Postgre를 받는 것을 끝냈습니다.SQL CHECK 제약 조건이 작동합니다.

Nilesh의 솔루션은 완전하지 않습니다. db/schema.rb 파일은 제약 조건을 포함하지 않으므로 db:setup을 사용하는 테스트 및 배포는 제약 조건을 얻지 못합니다.http://guides.rubyonrails.org/migrations.html#types-of-schema-dumps 에 따름

마이그레이션에서 사용자 지정 SQL 문을 실행할 수 있지만 스키마 덤프는 데이터베이스에서 해당 문을 재구성할 수 없습니다.이러한 기능을 사용하는 경우 스키마 형식을 :sql로 설정해야 합니다.

즉, config/application.rb 집합에 있습니다.

config.active_record.schema_format = :sql

불행히도, 만약 당신이 Postgre를 사용한다면,SQL 결과 덤프를 로드할 때 오류가 발생할 수 있습니다. 오류: 언어 plpgsql의 소유자여야 합니다.저는 포스트그리로 가고 싶지 않았습니다.해당 토론의 SQL 구성 경로. 또한 어떤 경우에도 읽을 수 있는 db/schema.rb 파일이 좋습니다.따라서 마이그레이션 파일에서 사용자 지정 SQL은 제외되었습니다.

Valera가 제안한 https://github.com/vprokopchuk256/mv-core 보석은 유망한 것처럼 보이지만 제한된 제약 조건만을 지원합니다. (그리고 그것을 사용하려고 할 때 오류가 발생했습니다. 비록 그것은 제가 포함하고 있는 다른 보석과의 비호환성 때문일 수도 있습니다.)

제가 함께 했던 해결책(해킹)은 모델 코드가 제약 조건을 삽입하도록 하는 것입니다.검증과 같은 것이기 때문에 여기에 설명합니다.

class MyModel < ActiveRecord::Base

    validates :my_constraint

    def my_constraint
        unless MyModel.connection.execute("SELECT * FROM information_schema.check_constraints WHERE constraint_name = 'my_constraint'").any?
            MyModel.connection.execute("ALTER TABLE my_models ADD CONSTRAINT my_constraint CHECK ( ...the SQL expression goes here ... )")
        end
    end

물론 각 검증 전에 추가로 선택합니다. 문제가 있다면 레일을 사용하여 오라클에 연결한 후 특정 스크립트를 실행하는 방법에 설명된 것과 같은 "연결 후" 원숭이 패치에 추가하는 것이 솔루션입니다. (검증/제약 추가는 트랜잭션 내에서 발생하므로 선택 결과를 단순히 캐시할 수 없습니다.)이온이 롤백될 수 있으므로 매번 확인해야 합니다.)

사용할 수 있습니다.Sequel보석 https://github.com/jeremyevans/sequel

Sequel.migration do
  change do
    create_table(:artists) do
      primary_key :id
      String :name
      constraint(:name_min_length){char_length(name) > 2}
    end
  end
end

언급URL : https://stackoverflow.com/questions/4664520/how-do-i-add-a-check-constraint-in-a-rails-migration