Rails 3-Migrationen: Referenzspalte hinzufügen?


161

Wenn ich eine neue Rails 3-Migration mit (zum Beispiel) erstelle

rails g migration tester title:tester user:references

, alles funktioniert gut ... aber wenn ich eine Spalte mit etwas in der Art von:

rails g migration add_user_to_tester user:references

Das Referenzfeld wird nicht erkannt. Kurz gesagt lautet die Frage: Wie füge ich einer Rails-Migration über die Befehlszeile eine Referenzierungsspalte hinzu?

Antworten:


205

Wenn Sie Rails 4.x verwenden , können Sie jetzt Migrationen mit folgenden Referenzen generieren:

rails generate migration AddUserRefToProducts user:references

wie Sie auf Schienen Führungen sehen können


1
Siehe beispielsweise Abschnitt 2.1 von edgeguides.rubyonrails.org/active_record_migrations.html .
B Sieben

2
Wie geben Sie einen Spaltennamen für den Fremdschlüssel anstelle des automatisch generierten Namens an?
J wird

@jwill können Sie polymorph verwenden: user: references {polymorphic}.
Paulo Fidalgo

@PauloFidalgo Kannst du ein bisschen erklären, wie das geht? kann eine Anleitung von Links sein? (spricht über polymorph)
Anwar


186

EDIT : Dies ist eine veraltete Antwort und sollte nicht beantragt werden Rails 4.x +

Sie müssen keine Referenzen hinzufügen, wenn Sie Ihrer referenzierten Klasse eine Ganzzahl-ID verwenden können.

Ich würde sagen, der Vorteil der Verwendung von Referenzen anstelle einer einfachen Ganzzahl besteht darin, dass das Modell mit Gehör zu vordefiniert wird. Da das Modell bereits erstellt wurde und bei der Migration eines vorhandenen Modells nicht betroffen ist, geht der Zweck verloren.

Also würde ich stattdessen folgendes tun:

rails g migration add_user_id_to_tester user_id:integer

Fügen Sie dann im System Tester manuell Gehör zu: Benutzer hinzu


9
Dies führt jedoch nicht zu den entsprechenden Fremdschlüsseleinschränkungen für Datenbanken, die dies unterstützen, oder?
Abahgat

19
Nein, afaik Rails erstellt niemals Fremdschlüsseleinschränkungen in der Datenbank, es sei denn, Sie fügen Plugins hinzu, um dies für Sie zu tun.
DanneManne

Ich studiere gerade diesen Beitrag und bitte, wie füge ich die Referenz hinzu
El Nino


3
Die Antwort ist veraltet, siehe @ Paulos Antwort für moderne Schienen.
OneHoopyFrood

102

Bitte beachten Sie, dass Sie höchstwahrscheinlich auch einen Index für diese Spalte benötigen.

class AddUserReferenceToTester < ActiveRecord::Migration
  def change
    add_column :testers, :user_id, :integer
    add_index  :testers, :user_id
  end
end

1
Warum? Gilt das für die meisten zugehörigen Beziehungen?
Ahnbizcad

Es ist in der Tat aus Leistungsgründen und praktisch, wenn Sie ein has_many / has_one auf der anderen Seite dieser Beziehung haben. Wenn Sie absolut sicher sind, dass Sie nicht durchlaufen werden user.testers, können Sie den Index weglassen.
Eugene

1
Das rails g migration ...Generierte, add_reference :installs, :device, index: truedas auch den Index erstellt.
B Sieben

49

Mit den beiden oben genannten vorherigen Schritten fehlt Ihnen immer noch die Fremdschlüsseleinschränkung. Das sollte funktionieren:

  class AddUserReferenceToTester < ActiveRecord::Migration
      def change
          add_column :testers, :user_id, :integer, references: :users
      end
  end

Dies ist die einzige tatsächliche Antwort hier. Der Fremdschlüssel ist hier der kritischste Teil
user2490003

Dies sollte als die richtige Antwort markiert werden, da die Fragen nach Schienen 3
Carlos Roque

35

Sie können Referenzen in einer Änderungsmigration verwenden. Dies ist ein gültiger Rails 3.2.13-Code:

class AddUserToTester < ActiveRecord::Migration
  def change
    change_table :testers do |t|
      t.references :user, index: true 
    end
  end
  def down
    change_table :testers do |t|
      t.remove :user_id
    end
  end
end

Vgl.: http://apidock.com/rails/ActiveRecord/ConnectionAdapters/SchemaStatements/change_table


1
Methoden ändern und herunterfahren? sind nicht stattdessen Up- und Down-Methoden?
MaicolBen

@MaicolBen ja, und Sie können auch einfach die Down-Methode weglassen.
Hut8

@MaicolBen Ohne die downMethode habe ich ActiveRecord::IrreversibleMigrationbeim Rollback mit Rails 3.2 bekommen. Ich auch ändern musste changezu up.
Andrew Grimm

27

Durch Ausführen rails g migration AddUserRefToSponsors user:referenceswird die folgende Migration generiert:

def change
  add_reference :sponsors, :user, index: true
end

Für welche Version von Rails ist das?
Andrew Grimm

8

Wenn Sie eine Spalte hinzufügen, müssen Sie diese Spalte zu einer Ganzzahl machen und wenn möglich die Schienenkonventionen einhalten. Für Ihren Fall gehe ich also davon aus, dass Sie bereits über Tester- und Benutzermodelle sowie Tester- und Benutzertabellen verfügen.

Um den Fremdschlüssel hinzuzufügen, müssen Sie eine Ganzzahlspalte mit dem Namen user_id (Konvention) erstellen:

add_column :tester, :user_id, :integer

Fügen Sie dann dem Testermodell ein Gehorsam hinzu:

class Tester < ActiveRecord::Base
  belongs_to :user
end

Vielleicht möchten Sie auch einen Index für den Fremdschlüssel hinzufügen (dies ist etwas, was die Referenzen bereits für Sie tun):

add_index :tester, :user_id

8

Das wird den Trick machen:

rails g migration add_user_to_tester user_id:integer:index

Ich mag es, dass dies auch den Index hinzufügt, den Sie höchstwahrscheinlich wollen werden.
Bheeshmar

3

Sie können Ihrem Modell über die Befehlszeile auf folgende Weise Verweise hinzufügen:

rails g migration add_column_to_tester user_id:integer

Dadurch wird eine Migrationsdatei wie folgt generiert:

class AddColumnToTesters < ActiveRecord::Migration
  def change
    add_column :testers, :user_id, :integer
  end
end

Dies funktioniert jedes Mal gut, wenn ich es benutze.


3

Für Schienen 4

Der Generator akzeptiert den Spaltentyp als Referenz (auch verfügbar als belongs_to).

Diese Migration erstellt eine user_idSpalte und einen entsprechenden Index:

$ rails g migration AddUserRefToProducts user:references 

erzeugt:

class AddUserRefToProducts < ActiveRecord::Migration
  def change
    add_reference :products, :user, index: true
  end
end

http://guides.rubyonrails.org/active_record_migrations.html#creating-a-standalone-migration

Für Schienen 3

Der Helfer heißt Referenzen (auch verfügbar als belongs_to).

Diese Migration erstellt eine category_idSpalte des entsprechenden Typs. Beachten Sie, dass Sie den Modellnamen und nicht den Spaltennamen übergeben. Active Record fügt das _idfür Sie hinzu.

change_table :products do |t|
  t.references :category
end

Wenn Sie polymorphe belongs_toAssoziationen haben, fügen Referenzen beide erforderlichen Spalten hinzu:

change_table :products do |t|
  t.references :attachment, :polymorphic => {:default => 'Photo'}
end

Fügt eine Anhangs-ID-Spalte und eine Zeichenfolgenspalte attachment_typemit dem Standardwert von hinzu Photo.

http://guides.rubyonrails.org/v3.2.21/migrations.html#creating-a-standalone-migration

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.