Rails tiene y pertenece a muchas migraciones
Tengo dos modelos restaurant
y user
que quiero realizar una has_and_belongs_to_many relación.
Ya he entrado en los archivos del modelo y he añadido los has_and_belongs_to_many :restaurants
y has_and_belongs_to_many :users
Asumo que en este punto debería ser capaz de hacer algo como con Rails 3:
rails generate migration ....
Pero todo lo que he intentado parece fallar. Estoy seguro de que esto es algo muy simple Soy nuevo en rails, así que todavía estoy aprendiendo.
4 answers
Necesita agregar una tabla de unión separada con solo restaurant_id
y user_id
(sin clave primaria), en orden alfabético .
Primero ejecute sus migraciones y, a continuación, edite el archivo de migración generado.
Carriles 3
rails g migration create_restaurants_users_table
Rieles 4:
rails g migration create_restaurants_users
Carriles 5
rails g migration CreateJoinTableRestaurantUser restaurants users
De los documentos :
También hay un generador que producirá tablas de unión si JoinTable es parte de la nombre:
Su archivo de migración (tenga en cuenta el :id => false
; es lo que impide la creación de una clave primaria):
Carriles 3
class CreateRestaurantsUsers < ActiveRecord::Migration
def self.up
create_table :restaurants_users, :id => false do |t|
t.references :restaurant
t.references :user
end
add_index :restaurants_users, [:restaurant_id, :user_id]
add_index :restaurants_users, :user_id
end
def self.down
drop_table :restaurants_users
end
end
Carriles 4
class CreateRestaurantsUsers < ActiveRecord::Migration
def change
create_table :restaurants_users, id: false do |t|
t.belongs_to :restaurant
t.belongs_to :user
end
end
end
t.belongs_to
creará automáticamente los índices necesarios. def change
detectará automáticamente una migración hacia adelante o hacia atrás, sin necesidad de subir/bajar.
Carriles 5
create_join_table :restaurants, :users do |t|
t.index [:restaurant_id, :user_id]
end
Nota: También hay una opción para un nombre de tabla personalizado que se puede pasar como parámetro a create_join_table called table_name
. De los documentos
De forma predeterminada, el nombre de la tabla join proviene de la unión de los dos primeros argumentos proporcionados a create_join_table, en orden alfabético orden. Para personalizar el nombre de la tabla, proporcione un: table_name opción:
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-04-13 09:21:26
Las respuestas aquí son bastante anticuadas. A partir de Rails 4.0.2, tus migraciones hacen uso de create_join_table
.
Para crear la migración, ejecute:
rails g migration CreateJoinTableRestaurantsUsers restaurant user
Esto generará lo siguiente:
class CreateJoinTableRestaurantsUsers < ActiveRecord::Migration
def change
create_join_table :restaurants, :users do |t|
# t.index [:restaurant_id, :user_id]
# t.index [:user_id, :restaurant_id]
end
end
end
Si desea indexar estas columnas, descomente las líneas respectivas y ¡listo!
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-02-16 03:57:05
Al crear la tabla de unión, preste mucha atención al requisito de que las dos tablas deben enumerarse en orden alfabético en el nombre/clase de migración. Esto puede morderte fácilmente si los nombres de tus modelos son similares, por ejemplo, "abc" y "abb". Si tuvieras que correr
rails g migration create_abc_abb_table
Tus relaciones no funcionarán como se esperaba. Debe utilizar
rails g migration create_abb_abc_table
En su lugar.
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
2013-05-27 06:52:39
Para las relaciones HABTM, es necesario crear una tabla de unión. Solo hay tabla de unión y esa tabla no debe tener una columna id. Prueba esta migración.
def self.up
create_table :restaurants_users, :id => false do |t|
t.integer :restaurant_id
t.integer :user_id
end
end
def self.down
drop_table :restaurants_users
end
Debe comprobar esta relación rails guía tutoriales
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
2015-02-28 09:26:01