Rails: has_many mit zusätzlichen Details?
-
21-09-2019 - |
Frage
Während ich bin nicht ein kompletter Rubin / Rails newb, ich bin immer noch ziemlich grün und ich versuche, herauszufinden, wie einige Modellbeziehungen zu strukturieren. Das einfachste Beispiel, das ich denken kann, ist die Idee des „Rezepts“ für das Kochen.
Eine Rezeptur besteht aus einem oder mehreren Inhaltsstoffen und die damit verbundenen Menge jeden Bestandteil. Angenommen, wir in der Datenbank aller Bestandteile eine Masterliste haben. Das legt nahe, zwei einfache Modelle:
class Ingredient < ActiveRecord::Base
# ingredient name,
end
class Recipe < ActiveRecord::Base
# recipe name, etc.
end
Wenn wir nur zu assoziieren Rezepte mit Zutaten wollen, die als Zugabe des entsprechenden belongs_to
und has_many
als simpling ist.
Aber was, wenn wir zusätzliche Informationen mit dieser Beziehung verknüpft werden sollen? Jeder Recipe
hat eine oder mehr Ingredients
, aber wir wollen die Menge des Ingredient
anzuzeigen.
Was ist der Rails Weg, das zu modellieren? Ist es etwas entlang der Linien eines 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
Lösung
Rezepte und Zutaten haben eine hat und gehört zur Beziehung, aber Sie wollen für Link zusätzliche Informationen zu speichern.
Im Wesentlichen für das, was Sie suchen, ist ein reiches Modell verbinden. Aber eine has_and_belongs_to_many Beziehung ist nicht flexibel genug, um die zusätzliche Informationen zu speichern, die Sie benötigen. Stattdessen müssen Sie eine has_many verwenden:. Durch relatinship
Dies ist, wie ich es einrichten würde.
Rezepte Spalten: Anweisungen
class Recipe < ActiveRecord::Base
has_many :recipe_ingredients
has_many :ingredients, :through => :recipe_ingredients
end
Recipe_Ingredients Spalten: recipe_id, ingredient_id, Menge
class RecipeIngredients < ActiveRecord::Base
belongs_to :recipe
belongs_to :ingredient
end
Bestandteil Spalten: Name
class Ingredient < ActiveRecord::Base
has_many :recipe_ingredients
has_many :recipes, :through => :recipe_ingredients
end
Dies wird eine grundlegende Darstellung von dem, was Sie suchen zu tun. Sie können eine Validierung RecipeIngredients hinzufügen möchten, um sicherzustellen, dass jede Zutat einmal pro Rezept aufgeführt ist, und eine Callback-Duplikate zu einem Eintrag falten.
Andere Tipps
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
Wie wäre:
- Klasse Ingredient (gehört zu Rezept, hat viele ingredientrecipecounts)
- Klasse Rezept (viele Zutaten hat, viele ingredientrecipecounts hat)
- Klasse IngredientRecipeCount (gehört zur Zutat, gehört zu Rezepte)
Dies ist nicht so sehr die Rails Art und Weise, wie nur eine weitere Beziehung zwischen den Daten in der Datenbank zu etablieren. Es ist nicht wirklich ein „hat und gehört zu viele“, weil jede Zutat nur eine Zählung pro Rezept hat, und jedes Rezept eine Zählung pro Zutat .., die die gleiche Anzahl ist.