20

Estoy teniendo dificultades para descubrir cómo asociar uno de mis modelos con varios de otro.Modelo de rieles, pertenece a muchos

Como está ahora, que tengo:

class ModelA < ActiveRecord::Base 
    has_many :model_b 
end 

class ModelB < ActiveRecord::Base 
    belongs_to :model_a 
end 

Sin embargo ... ModelB tiene que pertenecer a no sólo una instancia de ModelA, pero posiblemente tres. Sé que hay un has_many: a través de, pero no estoy seguro de cómo funcionaría en este caso. CADA instancia de ModelA siempre tendrá exactamente tres instancias de ModelB. Pero como se dijo antes, ModelB puede pertenecer a más de una instancia de ModelA.

Respuesta

40

Relaciones muchas a muchas en rieles no usan belongs_to. En cambio, quieres usar una de las dos opciones. La primera es has_and_belongs_to_many:

# app/models/category.rb 
class Category < ActiveRecord::Base 
    has_and_belongs_to_many :items 
end 

# app/models/item.rb 
class Item < ActiveRecord::Base 
    has_and_belongs_to_many :categories 
end 

por lo que deberá añadir una tabla de unión adicional en su base de datos, con una migración de esta manera:

class AddCategoriesItems < ActiveRecord::Migration 
    def self.up 
    create_table :categories_items, :id => false do |t| 
     t.integer :category_id 
     t.integer :item_id 
    end 
    end 

    def self.down 
    drop_table :categories_items 
    end 
end 

Puede verse que el nombre de la tabla de unión es la combinación de los nombres de las otras dos tablas. Las tablas se deben mencionar en orden alfabético como se indica arriba, y el :id => false debe estar allí, ya que no queremos una clave principal en esta tabla. Rompe la asociación de los carriles.

También hay otro método más complejo conocido como has_many :through si necesita almacenar información acerca de la relación en sí. He escrito un artículo completo que detalla cómo hacer ambos métodos, y cuándo utilizar cada uno:

Basic many-to-many Associations in Rails

espero que esto ayude, y ponerse en contacto conmigo si tiene alguna otra pregunta!

+0

que fue realmente útil! Una adición útil sería algunos ejemplos sobre cómo podemos acceder a estas relaciones en el código (ya sea en un controlador o en una vista) gracias – msanjay

26

Esto es lo que @Jaime Bellmyer utiliza

# app/models/category.rb 
class Category < ActiveRecord::Base 
    has_and_belongs_to_many :items 
end 

# app/models/item.rb 
class Item < ActiveRecord::Base 
    has_and_belongs_to_many :categories 
end 

yo recomendaría usar este

# app/models/category.rb 
class Category < ActiveRecord::Base 
    has_many :category_items 
    has_many :items, :through => :category_items 
end 

# app/models/item.rb 
class Item < ActiveRecord::Base 
    has_many :category_items 
    has_many :categories, :through => :category_items 
end 

# app/models/category_items.rb 
class CategoryItems < ActiveRecord::Base 
    belongs_to :category 
    belongs_to :items 
end 

Si se utiliza este que tendrá un modelo que le dará un mayor control sobre la manipulación Categoría unen y Ít. Pero usando lo que @Jaime sugirió, tendrá solo una tabla de unión y no un modelo, que no estará bajo control.

+0

significa esto que debo sacar la clave externa de las tablas ya que están vinculadas por el unirse a la mesa? – Edmund

+0

Sí. No necesitará almacenar las claves externas en las tablas principales, las cuales pueden almacenarse en el modelo de unión. – Rohit

+0

¿Por qué no basta con decir Categoría has_many: elementos (un elemento pertenece a muchas categorías pero ActiveRecord no tiene esto) –

Cuestiones relacionadas