Rails: has_many avec des détails supplémentaires?
-
21-09-2019 - |
Question
Alors que je ne suis pas un complet Ruby / Rails newb, je suis encore assez vert et je suis en train de comprendre comment structurer des relations de modèle. L'exemple le plus simple que je peux penser est l'idée de « recettes » pour la cuisson.
Une recette se compose d'un ou plusieurs ingrédients et la quantité associée de chaque ingrédient. Supposons que nous avons une liste maîtresse dans la base de données de tous les ingrédients. Cela suggère deux modèles simples:
class Ingredient < ActiveRecord::Base
# ingredient name,
end
class Recipe < ActiveRecord::Base
# recipe name, etc.
end
Si nous voulions juste associer des recettes avec des ingrédients, qui est aussi simpling que l'ajout de la belongs_to
et has_many
approprié.
Mais si nous voulons associer des informations supplémentaires à cette relation? Chaque Recipe
a un ou plusieurs Ingredients
, mais nous voulons indiquer la quantité de Ingredient
.
Quelle est la façon Rails de modèle? Est-ce quelque chose le long des lignes d'un has_many through
?
class Ingredient < ActiveRecord::Base
# ingredient name
belongs_to :recipe_ingredient
end
class RecipeIngredient < ActiveRecord::Base
has_one :ingredient
has_one :recipe
# quantity
end
class Recipe < ActiveRecord::Base
has_many :recipe_ingredients
has_many :ingredients, :through => :recipe_ingredients
end
La solution
Recettes et ingrédients ont un a et appartient à plusieurs, mais vous voulez stocker des informations supplémentaires pour le lien.
Essentiellement ce que vous cherchez est un riche modèle de jointure. Mais, une relation has_and_belongs_to_many est pas assez souple pour stocker les informations supplémentaires dont vous avez besoin. vous hériterez besoin d'utiliser un has_many. par relatinship
Voici comment je le configurer.
colonnes de recettes: instructions
class Recipe < ActiveRecord::Base
has_many :recipe_ingredients
has_many :ingredients, :through => :recipe_ingredients
end
recipe_ingredients colonnes: recette_id, ingredient_id, la quantité
class RecipeIngredients < ActiveRecord::Base
belongs_to :recipe
belongs_to :ingredient
end
colonnes d'ingrédients: nom
class Ingredient < ActiveRecord::Base
has_many :recipe_ingredients
has_many :recipes, :through => :recipe_ingredients
end
Cela fournira une représentation de base de ce que vous cherchez à faire. Vous pouvez ajouter une validation à RecipeIngredients pour faire en sorte que chaque ingrédient est répertorié une fois par recette, et un rappel à plier les doublons dans une entrée.
Autres conseils
http://railsbrain.com /api/rails-2.3.2/doc/index.html?a=M001888&name=has_and_belongs_to_many
http://railsbrain.com /api/rails-2.3.2/doc/index.html?a=M001885&name=has_many
Que diriez-vous:
- classe Ingrédient (appartient à la recette, a beaucoup ingredientrecipecounts)
- Recette de classe (a de nombreux ingrédients, a beaucoup ingredientrecipecounts)
- classe IngredientRecipeCount (appartient à ingrédient, appartient à la recette)
Ce n'est pas tant les rails comme simplement établir une relation plus entre les données dans la base de données. Ce n'est pas vraiment un « a et appartient à un grand nombre » parce que chaque ingrédient a seulement un compte par recette, et chaque recette un compte par ingrédient .. Quel est le même chef d'accusation.