2011-01-22 13 views
12

Sto scrivendo uno script di migrazione per creare una tabella con una colonna chiave primaria denominata guid ed è una VARCHAR(25). Il problema è che mi sento come se dovessi raddoppiare i miei sforzi per ottenere ciò che dovrebbe essere possibile in un unico passaggio.Migrazione delle rotaie Crea tabella Chiave primaria

se corro:

create_table(:global_feeds, :primary_key => 'guid') do |t| 
    t.string :guid, :limit => 25 
    t.text :title 
    t.text :subtitle 

    ... 

    t.timestamps 
end 

ottengo una tabella con una chiave primaria chiamata guid nessuna colonna chiamato id (che è quello che voglio). Tuttavia, il problema è che la colonna guid è una INT(11) con l'incremento automatico attivato. Quindi devo eseguire un comando aggiuntivo:

change_column :global_feeds, :guid, :string, :limit => 25 

sembra un po 'contorto di dover correre sostanzialmente due comandi SQL per ottenere ciò che credo dovrebbe essere possibile in uno.

Qualche suggerimento su come ottimizzare questo?

risposta

19

suppongo che si sta utilizzando MySQL, ecco cosa si può provare

create_table :global_feeds, {:id => false} do |t| 
    t.string :guid 
    t.text :title 
    t.text :subtitle 
    t.timestamps 
end 
execute "ALTER TABLE global_feeds ADD PRIMARY KEY (guid);" 

Se non sei su mySQL è necessario modificare la query nel comando execute per lavorare al vostro motore di DB. Non sono sicuro di poterlo fare su SQLite. E non dimenticate di mettere questa linea da qualche parte nel modello global_feed.rb:

set_primary_key :guid 

In ogni caso il gioco è ottenere il massimo di Rails, mentre si sta attaccando alle sue convenzioni. Cambiare il nome e il tipo di chiave primaria potrebbe non essere una buona idea.

+0

Sfortunatamente, si tratta ancora di due istruzioni SQL come la mia. Hai appena capovolto l'ordine delle operazioni: stai definendo il tipo di colonna prima e poi specificando la chiave primaria. – Ryan

+0

Immagino che non puoi farlo in una sola operazione, ma immagino che non ci sia nulla di sbagliato in questo. È perfettamente ok per la migrazione avere due istruzioni per casi un po 'più complessi. –

+0

Inoltre non sono sicuro se ActiveRecord funzioni correttamente con chiavi primarie non intere. –

4

È necessario utilizzare #column anziché #string. Per esempio:

create_table(:global_feeds, :primary_key => 'guid') do |t| 
    t.column :guid, "varchar(25)", :null => false 
    ... 
end 

Nota che il tipo varchar non è portabile ai database diverso da MySQL.

+0

errore di sintassi ', imprevisto '(', in attesa di keyword_end t.column: guid,: varchar (26),: null => false' Con esso punta alla parentesi alla fine di varchar – Ryan

+0

Giusto. varchar (25) "' invece di ': varchar (25)'. – JellicleCat

3

Questo è possibile in Rails 3. prova:

def self.up 
    create_table(:signups, :id => false) do |t| 
     t.string :token, :primary => true 

check-out questa sostanza per una grande soluzione per l'utilizzo di UUID come primario col chiave: https://gist.github.com/937739

+2

Non ha funzionato per me su Rails 4 + MySQL – dolzenko

+0

Vedere risposta di @kakoni –

22

In Rails 4 si può fare;

create_table :global_feeds, id: false do |t| 
    t.string :guid, primary_key: true 
... 
end 
+1

Funziona perfettamente su binari 4! –

+1

questo non dovrebbe essere una stringa, mysql con uuid dovrebbe essere un binario (16) – Seed

+1

Funziona in Rails 5 :-) – Maybe1

0

In Rails 5, per thoes che ha ottenuto problema ArgumentError: Index name '*' on table '*' already exists quando rails db:setup con la migrazione dal @kakoni, i seguenti lavori per me

create_table(:global_feeds, primary_key: :guid, id: false) do |t| 
    t.string :guid 
... 
end 

Per ulteriori informazioni, consultare create_table.

Problemi correlati