답변:
마이그레이션에서 수행하면 다음과 같이 할 수 있습니다.
# Make sure no null value exist
MyModel.where(date_column: nil).update_all(date_column: Time.now)
# Change the column to not allow null
change_column :my_models, :date_column, :datetime, null: false
change
방법은이 경우에 적합하지 않습니다. (1)이 update_all
방법은 마이그레이션 및 잠재적 복귀 모두에서 실행 되기 때문 입니다. 최악의 상황은 아니지만 (2) 마이그레이션으로 인해 잠재적 인 되돌리기에서 열이 변경된 항목을 알 수있는 방법이 없기 때문입니다. 따라서이 경우에는 up
및을 사용 down
합니다.
Rails 4에서는 이것이 더 나은 (DRYer) 솔루션입니다.
change_column_null :my_models, :date_column, false
NULL
해당 열에 값이있는 레코드가 없는지 확인하려면 값이있는 레코드에 사용할 기본값 인 네 번째 매개 변수를 전달하면 NULL
됩니다.
change_column_null :my_models, :date_column, false, Time.now
change_column_null
합니다. 그러나 위의 Rick Smith의 의견은 매우 유효한 사례를 지적합니다.
Rails 4 (다른 Rails 4 답변에 문제가 있음) :
def change
change_column_null(:users, :admin, false, <put a default value here> )
# change_column(:users, :admin, :string, :default => "")
end
NULL을 허용하지 않도록 NULL 값이있는 열을 변경하면 문제가 발생합니다. 이것은 개발 설정에서 제대로 작동하고 LIVE 프로덕션에 배포하려고 할 때 충돌하는 코드 유형입니다 . 먼저 NULL 값을 유효한 것으로 변경 한 다음 NULL 을 허용하지 않아야합니다 . 네 번째 값 change_column_null
은 정확히 그렇게합니다. 자세한 내용은 설명서 를 참조하십시오.
또한 일반적으로 필드의 기본값을 설정하는 것을 선호하므로 새 객체를 만들 때마다 필드 값을 지정할 필요가 없습니다. 주석 처리 된 코드도 포함 시켰습니다.
add_column :users, :admin, :string
thenchange_column_null(:admin, :string, false, "new_value_for_existing_records")
값 이있는 change_column
명령문 이있는 마이그레이션을 작성하십시오 :default =>
.
change_column :my_table, :my_column, :integer, :default => 0, :null => false
참조 : change_column
데이터베이스 엔진에 따라 사용해야 할 수도 있습니다 change_column_null
change_column_null
.
레일 4 :
def change
change_column_null(:users, :admin, false )
end
기존 레코드가 있으면 add_timestamps 및 null : false를 사용할 수 없으므로 해결책은 다음과 같습니다.
def change
add_timestamps(:buttons, null: true)
Button.find_each { |b| b.update(created_at: Time.zone.now, updated_at: Time.zone.now) }
change_column_null(:buttons, :created_at, false)
change_column_null(:buttons, :updated_at, false)
end
MyModel.update_all({:date_column => Time.now}, {:date_column => nil})
. 원래 형식의 쿼리로 모든 모델의 필드 값이 0이되었습니다.