remove rails migrations has_and_belongs_to_many create ruby-on-rails rails-migrations

ruby-on-rails - rails - rake db:rollback



MigraciĆ³n de carriles: add_reference a Table pero diferente nombre de columna para Foreign Key than Rails Convention (6)

Tengo los siguientes dos modelos:

class Store < ActiveRecord::Base belongs_to :person end class Person < ActiveRecord::Base has_one :store end

Aquí está el problema: estoy tratando de crear una migración para crear la clave externa dentro de la tabla de personas. Sin embargo, la columna que hace referencia a la clave externa de Store no se llama store_id como sería la convención de rails, sino que se denomina foo_bar_store_id .

Si estuviera siguiendo la convención de rieles, haría la migración de esta manera:

class AddReferencesToPeople < ActiveRecord::Migration def change add_reference :people, :store, index: true end end

Sin embargo, esto no funcionará porque el nombre de la columna no es store_id, sino que es foo_bar_store_id . Entonces, ¿cómo especifico que el nombre de la clave externa es simplemente diferente, pero todavía mantengo index: true para mantener un rendimiento rápido?


Debajo de las cubiertas add_reference solo está delegando add_column y add_index por lo que solo tiene que encargarse usted mismo:

add_column :people, :foo_bar_store_id, :integer add_index :people, :foo_bar_store_id


En Rails 4.2, también puede configurar el modelo o la migración con un nombre de clave externa personalizado. En su ejemplo, la migración sería:

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

Here hay una interesante publicación de blog sobre este tema. Here está la sección semi-críptica en las Guías Rails. La publicación del blog definitivamente me ayudó.

En cuanto a las asociaciones, indique explícitamente la clave foránea o nombre de clase como este (creo que sus asociaciones originales se cambiaron ya que ''belongs_to'' entra en la clase con la clave externa):

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

Tenga en cuenta que el elemento class_name debe ser una cadena. El elemento foreign_key puede ser una cadena o un símbolo. Esto esencialmente le permite acceder a los ingeniosos accesos directos de ActiveRecord con sus asociaciones nombradas semánticamente, de la siguiente manera:

person = Person.first person.foo_bar_store # returns the instance of store equal to person''s foo_bar_store_id

belongs_to más información sobre las opciones de asociación en la documentación de belongs_to y has_one .


En su migración AddReferencesToPeople puede agregar manualmente el campo y el índice usando:

add_column :people, :foo_bar_store_id, :integer add_index :people, :foo_bar_store_id

Y luego, deje que su modelo conozca la clave externa de la siguiente manera:

class Person < ActiveRecord::Base has_one :store, foreign_key: ''foo_bar_store_id'' end


Para expandir la respuesta de Schpet, esto funciona en una directiva de migración create_table Rails 5 como esta:

create_table :chapter do |t| t.references :novel, foreign_key: {to_table: :books} t.timestamps end


en los rieles más nuevos puede agregar una clave externa a una tabla con un nombre diferente como este:

class AddFooBarStoreToPeople < ActiveRecord::Migration[5.0] def change add_reference :people, :foo_bar_store, foreign_key: { to_table: :stores } end end


# 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