Bir sütunu nasıl benzersiz hale getiririm ve Ruby on Rails geçişinde nasıl dizine eklerim?


416

uniqueRuby on Rails geçiş komut dosyasında bir sütun yapmak istiyorum . Bunu yapmanın en iyi yolu ne? Ayrıca bir tablodaki bir sütunu dizine eklemenin bir yolu var mı?

Ben uniquesadece kullanmak yerine bir veritabanındaki sütunları zorlamak istiyorum :validate_uniqueness_of.

Yanıtlar:


686

Rails'in eski sürümleri için kısa cevap (Rails 4+ için diğer cevaplara bakın):

add_index :table_name, :column_name, unique: true

Birden çok sütunu birlikte dizine eklemek için tek bir sütun adı yerine bir dizi sütun adı geçirirsiniz,

add_index :table_name, [:column_name_a, :column_name_b], unique: true

"Dizin adı ... çok uzun" name: "whatever"alırsanız, adı kısaltmak için add_index yöntemine ekleyebilirsiniz .

Ayrıntılı denetim için, executedüz SQL yürüten bir " " yöntemi vardır.

Bu kadar!

Bunu düzenli olarak eski model doğrulamaları için değiştiriyorsanız, nasıl çalıştığını kontrol edin. Kullanıcıya raporlama hatası, model düzeyinde doğrulamalar olmadan iyi olmayabilir. Her ikisini de yapabilirsiniz.


36
+1 validates_uniqueness_of kullanmaya devam etmeyi önerdiği için +1. Hata işleme her ikisini de öneririm tek bir endeksli sorgu maliyeti için bu yöntemi kullanarak çok daha temiz
Steve Weet

1
Çalışıyor gibi görünmediğini denedim! Benzersiz olarak tanımladığım sütun_adı ile iki kayıt ekleyebilirim! Rails 2.3.4 ve MySql herhangi bir fikir kullanıyorum?
Tam

Ben execute kullanarak ikinci öneri kullandım: execute "ALTER TABLE kullanıcıları ADI UNIQUE (e-posta)" ve işe yarıyor! ilk neden bilmemekle ilgilenmediğinden emin değilim
Tam

1
indexed columns are not uniqueBenzersiz bir dizin oluşturmaya çalışırken bir hata alırsanız , bunun nedeni tablodaki verilerin yinelenenler içermesi olabilir. Yinelenen verileri kaldırmayı ve taşımayı yeniden çalıştırmayı deneyin.
Hartley Brody

5
"Dizin adı ... çok uzun" alırsanız , adı kısaltmak , :name => "whatever"için add_indexyönteme ekleyebilirsiniz .
Rick Smith

129

raylar taşıma oluşturur add_index_to_table_name column_name: uniq

veya

raylar geçiş oluşturur add_column_name_to_table_name sütun_adı: string: uniq: index

üretir

class AddIndexToModerators < ActiveRecord::Migration
  def change
    add_column :moderators, :username, :string
    add_index :moderators, :username, unique: true
  end
end

Mevcut bir sütuna bir dizin ekliyorsanız, add_columnsatırı kaldırın veya yorum yapın veya bir onay işareti koyun

add_column :moderators, :username, :string unless column_exists? :moderators, :username

5
Bunu iptal ettim çünkü komut satırı formunu istedim. Ama ben belirtirken hatta sütun ekler çok aptalca add_index...değil add_column....
Tyler Collier

1
Yeap, belki bir sonraki versiyonda.
d.danailov

49

Bu henüz bahsedilmediğinden, ancak bu sayfayı bulduğumda sahip olduğum soruyu yanıtladığından, bir dizinin t.referencesveya yoluyla eklerken benzersiz olması gerektiğini de belirtebilirsiniz t.belongs_to:

create_table :accounts do |t|
  t.references :user, index: { unique: true } # or t.belongs_to

  # other columns...
end

(en azından raylar itibariyle 4.2.7)


42

Yeni bir tablo oluşturuyorsanız, satır içi kısayolu kullanabilirsiniz:

  def change
    create_table :posts do |t|
      t.string :title, null: false, index: { unique: true }
      t.timestamps
    end
  end

14

Rails 5 kullanıyorum ve yukarıdaki cevaplar harika çalışıyor; benim için de işe yarayan başka bir yol var (tablo adı :peopleve sütun adı :email_address)

class AddIndexToEmailAddress < ActiveRecord::Migration[5.0]
  def change
    change_table :people do |t|
      t.index :email_address, unique: true
    end
  end
end

1

Benzersiz anahtarın adını, rayların varsayılan unique_key adının DB'nin hata atabileceği kadar uzun olabileceği için eklemek isteyebilirsiniz.

Dizininize ad eklemek için name:seçeneği kullanın. Taşıma sorgusu şöyle görünebilir -

add_index :table_name, [:column_name_a, :column_name_b, ... :column_name_n], unique: true, name: 'my_custom_index_name'

Daha fazla bilgi - http://apidock.com/rails/ActiveRecord/ConnectionAdapters/SchemaStatements/add_index


1
add_index :table_name, :column_name, unique: true

Birden çok sütunu birlikte dizine eklemek için tek bir sütun adı yerine bir dizi sütun adı geçirirsiniz.


0

DB sütununa benzersiz eklemeyi kaçırdıysanız, alanın benzersiz olup olmadığını kontrol etmek için modelde bu doğrulamayı eklemeniz yeterlidir:

class Person < ActiveRecord::Base
  validates_uniqueness_of :user_name
end

Buraya bakın Yukarıda yalnızca test amaçlıdır, lütfen @Nate tarafından önerilen şekilde DB sütununu değiştirerek dizin ekleyin

daha fazla bilgi için lütfen indeks ile birlikte bakın


2
Ben sadece karşılık gelen bir dizin olmadan doğrulama ekleme tavsiye etmem. Daha iyi bir seçenek var olan kopyaları temizleyip dizini eklemektir. Aksi takdirde, mevcut verileri geçersiz kılma riskiniz vardır (bu, bu satırlardaki güncellemelerin başarısız olmasına neden olur) ve Rails onaylarını atlayan herhangi bir kodunuz varsa yine de kopyalarla karşılaşabilirsiniz. (örneğin, bir update_all veya doğrudan SQL ekleri çalıştırırken)
Nate
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.