Rails: has_many с дополнительными подробностями? - PullRequest
1 голос
/ 19 января 2010

Хотя я не полный новичок в 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

Ответы [ 2 ]

5 голосов
/ 19 января 2010

Рецепты и ингредиенты имеют отношение и принадлежат многим, но вы хотите хранить дополнительную информацию для ссылки.

По сути, вы ищете богатую модель соединения. Но отношение has_and_belongs_to_many недостаточно гибкое, чтобы хранить необходимую вам дополнительную информацию. Вместо этого вам нужно будет использовать has_many: through relatinship.

Вот как бы я это настроил.

рецепты колонок: инструкция

class Recipe < ActiveRecord::Base
  has_many :recipe_ingredients
  has_many :ingredients, :through => :recipe_ingredients
end

столбцы recipe_ingredients: recipe_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, чтобы гарантировать, что каждый ингредиент указан один раз для каждого рецепта, и обратный вызов, чтобы сложить дубликаты в одну запись.

0 голосов
/ 19 января 2010

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

Как насчет:

  1. Ингредиент класса (принадлежит рецептуре, имеет много ингредиентов и их количество)
  2. Класс Recipe (имеет много ингредиентов, имеет много ингредиентов и их количество)
  3. Класс IngredientRecipeCount (принадлежит ингредиенту, принадлежит рецепту)

Это не столько путь Rails, сколько просто создание еще одногосвязь между данными в базе данных.На самом деле это не «имеет и принадлежит многим», потому что каждый ингредиент имеет только один счет на рецепт, а каждый рецепт - один счет на ингредиент ... Что такое же количество.

...