2010-04-03 21 views
14

Sono un neofita di Ruby on Rails (conosco bene Ruby, però) e guardando gli strumenti di Migrazione, sembra davvero fantastico. Gli schemi di database possono finalmente (facilmente) andare nel controllo del codice sorgente.Chiavi esterne con ActiveRecord :: Migration di Rails?

Ora il mio problema con esso. Quando si utilizza Postgres come database, non imposta le chiavi esterne. Gradirei i vantaggi delle chiavi esterne nel mio schema come l'integrità referenziale. Quindi, come posso applicare le chiavi esterne con le migrazioni?

risposta

12

La filosofia di Rails è che i controlli di integrità sono la logica aziendale che appartiene al modello. Ecco perché stai vedendo ciò che stai vedendo nel DB; whatever_id è solo un int e non un "vero" fk in vista. Non è un errore, è di design ed è un po 'strano all'inizio. Generalmente l'unica ragione che spinge le persone a lavorare con fks nel livello di DB è quando il DB è accessibile da più di un'app o da un sistema legacy. C'è un sacco di discussione e di alcuni ottimi collegamenti qui: Why do Rails migrations define foreign keys in the application but not in the database?

+0

Bene, il mio obiettivo è un nuovo progetto e nessun'altra app lo accederà ... quindi forse non ne ho bisogno? Sembra strano sebbene lol – Earlz

+1

Sembra strano. Alla fine si vede il senso di esso però. Per risolvere il tuo problema di velocità di seguito, dovresti sfruttare il comando add_index nelle tue migrazioni. Un fk aggiunge automaticamente un indice al database. In Rails basta aggiungerli da soli, se necessario ... Se ricordi :) – mikewilliamson

+0

FYI fk = chiave esterna, int = integrità – Ameen

7

Check this out: http://github.com/matthuhiggins/foreigner

Ma prima assicuratevi di realmente bisogno di loro (ad esempio integrità referenziale è una cosa che in teoria non dovrebbe rompere fino a quando il codice è OK, e sai di :dependent => :destroy e la differenza fra user.delete e user.destroy).

+0

Beh, sto pensando non solo circa l'integrità referenziale, ma anche sui vantaggi di velocità delle chiavi esterne ogni volta che si partecipa a 2 key'd tavoli. – Earlz

+1

@Earlz, so che questa è una grande quantità di worm nella comunità di rail, ma se si utilizza mysql, sembra un gioco da ragazzi. Questo plugin funziona incredibilmente. 'FK in Rails == HAPPY' :) –

+2

BTW, lo stato di Rails su fks non influenza la velocità dei join, è comunque possibile definire un indice su qualsiasi campo. – sahglie

1

Ci sono un certo numero di plugin disponibili (ricerca di Google) per rotaie che creeranno chiavi esterne per voi quando si utilizza un simbolo speciale nei tuoi migrazioni (foreign_key_migrations è uno dal libro Advanced Rails Recipes). Ricorda che Rails non funziona bene con questo concetto, specialmente quando stai cercando di eliminare oggetti (come menzionato da glebm).

0

Mi sono appena imbattuto in questo post. Forse qualcuno lo troverà utile. È così che si creano i vincoli:

http://guides.rubyonrails.org/migrations.html#using-reversible

class ExampleMigration < ActiveRecord::Migration 
def change 
create_table :products do |t| 
    t.references :category 
end 

reversible do |dir| 
    dir.up do 
    #add a foreign key 
    execute <<-SQL 
     ALTER TABLE products 
     ADD CONSTRAINT fk_products_categories 
     FOREIGN KEY (category_id) 
     REFERENCES categories(id) 
    SQL 
    end 
    dir.down do 
    execute <<-SQL 
     ALTER TABLE products 
     DROP FOREIGN KEY fk_products_categories 
    SQL 
    end 
end 

add_column :users, :home_page_url, :string 
rename_column :users, :email, :email_address 
end 
Problemi correlati