Especificar el nombre de la columna en una migración de "referencias"


Quiero hacer un migration en Rails, haciendo referencia a otra tabla. Por lo general, haría algo como:

add_column :post, :user, :references

Esto crea una columna llamada user_id en la tabla posts. Pero, ¿y si, en lugar de user_id, quiero algo como author_id? ¿Cómo puedo hacer eso?

Author: Sheharyar, 2012-12-04

6 answers

Hazlo manualmente:

add_column :post, :author_id, :integer

Pero ahora, cuando cree la instrucción belongs_to, tendrá que modificarla, por lo que ahora tiene que llamar a

def post
    belongs_to :user, :foreign_key => 'author_id'
end
 43
Author: mschultz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-12-04 01:35:12

En Rails 4.2+ también puede establecer claves foráneas en la base de datos, que es una gran idea.

Para asociaciones simples esto se puede hacer también en t.references agregando foreign_key: true, pero en este caso necesitará dos líneas.

# The migration
add_reference :posts, :author, index: true
add_foreign_key :posts, :users, column: :author_id

# The model
belongs_to :author, class_name: "User"
 203
Author: ecoologic,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-02-06 11:42:38

Para los carriles 5 +

Definición inicial:

Si está definiendo su tabla modelo Post, puede establecer references, index y foreign_key en una línea:

t.references :author, index: true, foreign_key: { to_table: :users }

Actualización existente:

Si está agregando referencias a una tabla existente, puede hacer esto:

add_reference :posts, :author, foreign_key: { to_table: :users }

Nota: El valor predeterminado de index es true.

 146
Author: Sheharyar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-03-26 22:35:32

En rails 4, cuando se utiliza postgresql y la gema schema_plus se puede escribir

add_reference :posts, :author, references: :users

Esto creará una columna author_id, que se refiere correctamente a users(id).

Y en tu modelo, escribes

belongs_to :author, class_name: "User"
 77
Author: nathanvda,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-01-27 15:02:26

Si no está utilizando una clave foránea, entonces no importa cuál sea el nombre real de la tabla de la otra tabla.

add_reference :posts, :author

A partir de Rails 5 , si está utilizando una clave foránea, puede especificar el nombre de la otra tabla en las opciones de clave foránea. (véase https://github.com/rails/rails/issues/21563 {[9] } para discusión)

add_reference :posts, :author, foreign_key: {to_table: :users}

Antes de Rails 5, debe agregar la clave foránea como un paso separado:

add_foreign_key :posts, :users, column: :author_id
 45
Author: jes5199,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-02-05 19:02:58

Alias_attribute(new_name, old_name) es muy práctico. Simplemente crea tu modelo y la relación:

rails g model Post title user:references

Luego edite el modelo y agregue un alias de atributo con

alias_attribute :author, :user

Después de eso podrás ejecutar cosas como

Post.new(title: 'My beautiful story', author: User.first)
 -2
Author: sekmo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-03-30 16:11:29