Ich habe die folgenden zwei Modelle:
class Store < ActiveRecord::Base
belongs_to :person
end
class Person < ActiveRecord::Base
has_one :store
end
Hier ist das Problem: Ich versuche, eine Migration zu erstellen, um den Fremdschlüssel in der Personentabelle zu erstellen. Die Spalte, die sich auf den Fremdschlüssel von Store bezieht, heißt jedoch nicht store_id, wie dies bei der Rails-Konvention der Fall wäre, sondern foo_bar_store_id .
Wenn ich der Rails-Konvention folgen würde, würde ich die Migration folgendermaßen durchführen:
class AddReferencesToPeople < ActiveRecord::Migration
def change
add_reference :people, :store, index: true
end
end
Dies funktioniert jedoch nicht, da der Spaltenname nicht store_id, sondern foo_bar_store_id lautet . Wie gebe ich an, dass der Fremdschlüsselname nur anders ist, aber dennoch den Index: true beibehält, um eine schnelle Leistung zu gewährleisten?
add_foreign_key :people, :stores, column: :foo_bar_store_id
add_foreign_key
wurde hier bereits durch eine andere Antwort abgedeckt.foo_bar_store_id
kann auf eine ungültige Geschäfts-ID gesetzt werden, und das Modell besteht alle Überprüfungen. Korrigieren Sie mich, wenn ich falsch liege, aber wenn Sie nur diese Zeile in das Modell einfügen, werfen die Schienen beim Speichern keinen ActiveRecord :: InvalidForeignKey: PG :: ForeignKeyViolation: ERROR-Fehler.In Rails 5.x können Sie einer Tabelle mit einem anderen Namen wie diesem einen Fremdschlüssel hinzufügen:
class AddFooBarStoreToPeople < ActiveRecord::Migration[5.0] def change add_reference :people, :foo_bar_store, foreign_key: { to_table: :stores } end end
quelle
create_table
Richtung wie:t.references :feature, foreign_key: {to_table: :product_features}
incoming_location_id
in Tabelleinventory_incomings
stimmt nicht mit Spalteid
auf übereinaddresses
, die Typ hatbigint(20)
. Um dieses Problem zu beheben, ändern Sie den Typ derincoming_location_id
Spalteinventory_incomings
in: bigint.In Rails 4.2 können Sie das Modell oder die Migration auch mit einem benutzerdefinierten Fremdschlüsselnamen einrichten. In Ihrem Beispiel wäre die Migration:
class AddReferencesToPeople < ActiveRecord::Migration def change add_column :people, :foo_bar_store_id, :integer, index: true add_foreign_key :people, :stores, column: :foo_bar_store_id end end
Hier ist ein interessanter Blog-Beitrag zu diesem Thema. Hier ist der halbkryptische Abschnitt in den Rails Guides. Der Blog-Beitrag hat mir definitiv geholfen.
Geben Sie für Assoziationen den Fremdschlüssel oder Klassennamen explizit wie folgt an (ich denke, Ihre ursprünglichen Assoziationen wurden geändert, da das 'Gehört_zu' in der Klasse mit dem Fremdschlüssel steht):
class Store < ActiveRecord::Base has_one :person, foreign_key: :foo_bar_store_id end class Person < ActiveRecord::Base belongs_to :foo_bar_store, class_name: 'Store' end
Beachten Sie, dass das Element class_name eine Zeichenfolge sein muss. Das Element alien_key kann entweder eine Zeichenfolge oder ein Symbol sein. Auf diese Weise können Sie im Wesentlichen auf die raffinierten ActiveRecord-Verknüpfungen mit Ihren semantisch benannten Zuordnungen zugreifen, z.
person = Person.first person.foo_bar_store # returns the instance of store equal to person's foo_bar_store_id
Weitere Informationen zu den Zuordnungsoptionen finden Sie in der Dokumentation zu gehör_zu und has_one .
quelle
Um die Antwort von schpet zu erweitern, funktioniert dies in einer
create_table
Rails 5-Migrationsanweisung wie folgt :create_table :chapter do |t| t.references :novel, foreign_key: {to_table: :books} t.timestamps end
quelle
t.references :novel, foreign_key: {to_table: :books}
wird in der Rails-API-Dokumentation dargestellt, es werden jedoch keine zusätzlichen Optionen für Fremdschlüssel dargestellt oder erwähnt. Solche Optionen finden Sie in den Dokumenten für die Methode# Migration change_table :people do |t| t.references :foo_bar_store, references: :store #-> foo_bar_store_id end # Model # app/models/person.rb class Person < ActiveRecord::Base has_one :foo_bar_store, class_name: "Store" end
quelle
Unter dem Deckmantel delegiert add_reference nur an add_column und add_index, sodass Sie sich nur selbst darum kümmern müssen:
add_column :people, :foo_bar_store_id, :integer add_index :people, :foo_bar_store_id
quelle
has_one :store, foreign_key: 'foo_bar_store_id'