Jak zrobić kolumnę unikalną i indeksować ją w Ruby on Rails migration?
Chciałbym utworzyć kolumnę unique
w Ruby on Rails migration script. Jak najlepiej to zrobić? Czy istnieje również sposób na indeksowanie kolumny w tabeli?
Chciałbym wymuszać unique
kolumny w bazie danych, a nie tylko używać :validate_uniqueness_of
.
7 answers
Krótka odpowiedź:
add_index :table_name, :column_name, unique: true
Aby indeksować wiele kolumn razem, przekazujesz tablicę nazw kolumn zamiast nazwy pojedynczej kolumny,
add_index :table_name, [:column_name_a, :column_name_b], unique: true
Dla drobniejszych kontroli istnieje metoda" execute
", która wykonuje prosty SQL.
Jeśli robisz to jako zamiennik dla zwykłych walidacji starego modelu, po prostu sprawdź, jak to działa. Nie jestem pewien, czy zgłaszanie błędów do użytkownika będzie tak miłe. Zawsze możesz zrobić jedno i drugie.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-07 14:24:28
Rails generuje migrację add_index_to_table_name column_name: uniq
Lub
Rails generuje migrację add_column_name_to_table_name column_name: string: uniq: index
Generuje
class AddIndexToModerators < ActiveRecord::Migration
def change
add_column :moderators, :username, :string
add_index :moderators, :username, unique: true
end
end
Jeśli dodajesz indeks do istniejącej kolumny, Usuń lub skomentuj linię add_column
lub włóż czek
add_column :moderators, :username, :string unless column_exists? :moderators, :username
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-10 16:04:06
Ponieważ nie zostało to jeszcze wspomniane, ale odpowiada na pytanie, które miałem, gdy znalazłem tę stronę, możesz również określić, że indeks powinien być unikalny podczas dodawania go przez t.references
lub t.belongs_to
:
create_table :accounts do |t|
t.references :user, index: { unique: true } # or t.belongs_to
# other columns...
end
(od co najmniej Rails 4.2.7
)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-10 17:30:42
Jeśli tworzysz nową tabelę, możesz użyć skrótu w wierszu:
def change
create_table :posts do |t|
t.string :title, null: false, index: { unique: true }
t.timestamps
end
end
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-07 15:12:54
Używam Rails 5 i powyższe odpowiedzi działają świetnie; oto inny sposób, który również działał dla mnie (nazwa tabeli to :people
, a nazwa kolumny to :email_address
)
class AddIndexToEmailAddress < ActiveRecord::Migration[5.0]
def change
change_table :people do |t|
t.index :email_address, unique: true
end
end
end
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-11-10 16:52:42
add_index :table_name, :column_name, unique: true
Aby indeksować wiele kolumn razem, przekazujesz tablicę nazw kolumn zamiast nazwy pojedynczej kolumny.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-29 08:55:15
Możesz dodać nazwę dla unikalnego klucza, ponieważ domyślna nazwa unique_key przez rails może być zbyt długa, przez co DB może wyrzucić błąd.
Aby dodać nazwę dla indeksu wystarczy użyć opcji name:
.
Zapytanie o migrację może wyglądać mniej więcej tak -
add_index :table_name, [:column_name_a, :column_name_b, ... :column_name_n], unique: true, name: 'my_custom_index_name'
Więcej informacji - http://apidock.com/rails/ActiveRecord/ConnectionAdapters/SchemaStatements/add_index
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-05 11:39:56