2010-05-29 3 views
67

quindi ho una CREATE_TABLE come questo per corsi presso una scuola:Migrazione delle rotaie: t.ferenze con nome alternativo?

create_table :courses do |t| 
    t.string :name 
    t.references :course 
    t.timestamps 
end 

ma voglio che riferimento due altri corsi come:

has_many :transferrable_as # A Course 
has_many :same_as   # Another Course 

Posso dire quanto segue?

t.references :transferrable_as, :as=> :course 

risposta

12

penso che questa discussione ha un modo più Rails-ish diversa: Scaffolding ActiveRecord: two columns of the same data type

Nella migrazione:

t.belongs_to: transferrable_as

t.belongs_to: same_as

+1

ma come fa il db sapere quale chiave esterna per collegare il tavolo per? Sto provando questo con il database Postgres e mi sta dando un errore 'PG :: UndefinedTable: ERROR' sta cercando di aggiungere un vincolo di chiave esterna a una tabella che non esiste. –

+0

L'OA può commentare perché ha accettato questa risposta? 'belongs_to' è solo un alias per' references' che hai già provato. Se la migrazione ha funzionato, l'hai modificata in qualche modo da questa risposta? –

+0

L'ho risolto. Vedi la mia risposta a questa domanda –

3

Non credo references accetta l'opzione :as, ma è possibile creare le colonne manualmente ...

create_table :courses do |t| 
    t.string :name 
    t.integer :course1_id 
    t.integer :course2_id 
    t.timestamps 
end 
68

Si può fare in questo modo:

create_table :courses do |t| 
    t.string :name 
    t.references :transferrable_as, references: :courses 
    t.references :same_as, references: :courses 
    t.timestamps 
end 

o utilizzando t.belongs_to come alias per t.references

Non è possibile aggiungi foreign_key: true a quelle due linee di riferimento. Se si desidera contrassegnare loro come chiavi esterne a livello di database è necessario disporre di una migrazione con questo:

add_foreign_key :courses, :courses, column: :transferrable_as_id 
add_foreign_key :courses, :courses, column: :same_as_id 
+4

La parte relativa alla mancata aggiunta di 'foreign_key: true' alle linee di riferimento è stata la cosa che mi ha incitato. Aggiungere il 'add_foreign_key' e specificare il nome della colonna per quelli ha fatto il trucco. –

+0

Funziona fuori dalla scatola in Rails? Secondo http://stackoverflow.com/a/22384289/239657, ciò richiede la gemma 'schema_plus'. I documenti [add_reference] (http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/SchemaStatements.html#method-i-add_reference) di Rails non menzionano a: riferimenti opzioni. –

+0

Funziona fuori dalla scatola su Rails 4.2 nella mia esperienza. Osservazione interessante su tale opzione o non essere nei documenti. Questi documenti dicono anche che l'opzione: foreign_key è disponibile ma ho scoperto che non lo era. Forse un metodo diverso viene chiamato in qualche modo. –

3

Come risposta aggiunto a questa domanda - il modello dovrebbe avere la seguente riga per completare l'associazione:

belongs_to :transferrable_as, class_name: "Course" 
    belongs_to :same_as, class_name: "Course" 
62

È possibile fare tutto questo nella definizione di migrazione/colonna iniziale (almeno attualmente in Rails 5):

t.references :transferable_as, index: true, foreign_key: { to_table: :courses } 
t.references :same_as, index: true, foreign_key: { to_table: :courses } 
+6

Funziona su Rails 5.1 e nessuno degli altri suggerimenti fa. È molto più pulito e sembra giusto. – stephenmurdoch

+2

Io uso Rails 5.1.4 ma non funziona. Quando indico un'opzione 'foreign_key' nella creazione della tabella in questo modo, solleva un errore dicendo che la stessa tabella che sto creando non esiste ... Quindi sospetto che non sia realmente supportato dall'API ufficiale. – Quv