Domanda

Mentre io non sono un completo newb di Ruby / Rails, sono ancora abbastanza verde e sto cercando di capire come strutturare alcune relazioni modello. L'esempio più semplice che posso pensare è l'idea di "ricette" per cucinare.

Una ricetta è costituita da uno o più ingredienti e la quantità di ogni ingrediente associato. Supponiamo di avere un elenco principale nel database di tutti gli ingredienti. Questo suggerisce due modelli semplici:

class Ingredient < ActiveRecord::Base
  # ingredient name, 
end

class Recipe < ActiveRecord::Base
  # recipe name, etc.
end

Se volevamo solo ad associare ricette con gli ingredienti, che è come simpling come l'aggiunta del belongs_to e has_many appropriata.

Ma cosa succede se vogliamo associare informazioni aggiuntive con quel rapporto? Ogni Recipe ha uno o più Ingredients, ma vogliamo indicare la quantità del Ingredient.

Qual è il modo Rails per modellare questo? E 'qualcosa lungo le linee di 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
È stato utile?

Soluzione

Ricette e ingredienti hanno un ha e appartiene a molti, ma si desidera memorizzare informazioni aggiuntive per il link.

In sostanza quello che stai cercando è un ricco join modello. Ma, un rapporto has_and_belongs_to_many non è abbastanza flessibile per memorizzare le ulteriori informazioni necessarie. Invece è necessario utilizzare un has_many:. Attraverso relatinship

Questo è come vorrei configurarlo.

colonne ricette: istruzioni

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

recipe_ingredients colonne: recipe_id, ingredient_id, la quantità

class RecipeIngredients < ActiveRecord::Base
  belongs_to :recipe
  belongs_to :ingredient
end

colonne ingrediente: nome

class Ingredient < ActiveRecord::Base
  has_many :recipe_ingredients
  has_many :recipes, :through => :recipe_ingredients
end

Ciò fornirà una rappresentazione di base di quello che stai cercando di fare. Si consiglia di aggiungere una convalida per RecipeIngredients per garantire che ogni ingrediente è elencata una volta per ogni ricetta, e una funzione di callback per piegare i duplicati in una voce.

Altri suggerimenti

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

Come su:

  1. class Ingrediente (appartiene alla ricetta, ha molti ingredientrecipecounts)
  2. class Ricetta (ha molti ingredienti, ha molti ingredientrecipecounts)
  3. class IngredientRecipeCount (appartiene alla ingrediente, appartiene alla ricetta)

Questa non è tanto il modo delle rotaie come solo stabilire un altro rapporto tra i dati nel database. Non è proprio un "ha e appartiene a molti" perché ogni ingrediente ha un solo numero per ogni ricetta, e ogni ricetta un conteggio per ingrediente .. che è lo stesso numero.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top