Рельсы:has_many с дополнительной информацией?
-
21-09-2019 - |
Вопрос
Хотя я не полный новичок в Ruby/Rails, я все еще совсем новичок и пытаюсь понять, как структурировать некоторые взаимосвязи между моделями.Самый простой пример, который я могу придумать, — это идея «рецептов» приготовления пищи.
Рецепт состоит из одного или нескольких ингредиентов и соответствующего количества каждого ингредиента.Предположим, у нас есть основной список всех ингредиентов в базе данных.Это предполагает две простые модели:
class Ingredient < ActiveRecord::Base
# ingredient name,
end
class Recipe < ActiveRecord::Base
# recipe name, etc.
end
Если бы мы просто хотели связать рецепты с ингредиентами, это было бы так же просто, как добавить соответствующий belongs_to
и has_many
.
Но что, если мы хотим связать с этими отношениями дополнительную информацию?Каждый Recipe
имеет один или несколько Ingredients
, но мы хотим указать количество Ingredient
.
Как Rails может это смоделировать?Это что-то вроде 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
Решение
Рецепты и ингредиенты имеют отношения «имеет» и «принадлежит многим», но вы хотите сохранить дополнительную информацию для ссылки.
По сути, вам нужна богатая модель соединения.Однако связь has_and_belongs_to_many недостаточно гибка для хранения необходимой вам дополнительной информации.Вместо этого вам нужно будет использовать has_many :through relatinship.
Вот как бы я это настроил.
колонки рецептов:инструкции
class Recipe < ActiveRecord::Base
has_many :recipe_ingredients
has_many :ingredients, :through => :recipe_ingredients
end
Столбцы рецепта_ингредиентов:id_рецепта, id_ингредиента, количество
class RecipeIngredients < ActiveRecord::Base
belongs_to :recipe
belongs_to :ingredient
end
столбцы ингредиентов:имя
class Ingredient < ActiveRecord::Base
has_many :recipe_ingredients
has_many :recipes, :through => :recipe_ingredients
end
Это даст базовое представление о том, что вы хотите сделать.Возможно, вы захотите добавить проверку RecipeIngredients, чтобы гарантировать, что каждый ингредиент указан один раз для каждого рецепта, и обратный вызов для объединения дубликатов в одну запись.
Другие советы
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
Как насчет:
- класс Ingredient (принадлежит рецепту, имеет множество рецептов ингредиентов)
- Рецепт класса (содержит много ингредиентов, имеет много рецептов ингредиентов)
- класс IngredientRecipeCount (принадлежит ингредиенту, принадлежит рецепту)
Это не столько путь Rails, сколько просто установление еще одного отношения между данными в базе данных.На самом деле это не фраза «принадлежит многим», потому что каждый ингредиент имеет только одно количество в каждом рецепте, а в каждом рецепте — одно количество для каждого ингредиента.Это тот же самый счет.