J'ai une table d'ingrédients. Lorsqu'un utilisateur entre un ingrédient, il enregistre dans le tableau. Maintenant, ce que je remarque, c'est que de nombreux enregistrements se répètent, et je ne le veux pas, ce que je veux c'est que chacun de ces enregistrements soit référencé s'il existe déjà. Par exemple, j'ai de la farine sauvée environ 20 fois dans la base de données (DB). Je veux qu'il soit sauvegardé une fois, et pour chaque recette, quand un utilisateur entre de la farine, il devrait simplement faire référence à cet ingrédient dans la base de données. Comment puis-je y parvenir?Comment stocker un enregistrement une fois et le référencer plusieurs fois dans d'autres tables?
J'ai déjà un modèle d'entrée (recette), et un modèle EntryIngredient de jointure. Donc, chaque fois qu'une entrée enregistre un ingrédient qui existe déjà, je veux qu'il se réfère simplement à celui de la table EntryIngredient (en tant que clé étrangère) au lieu d'en créer un nouveau.
class Ingredient < ActiveRecord::Base
has_many :entry_ingredients
has_many :entries, :through => :entry_ingredients
end
class EntryIngredient < ActiveRecord::Base
belongs_to :entry
belongs_to :ingredient
accepts_nested_attributes_for :ingredient, :reject_if => lambda { |a| a[:name].blank? }, :allow_destroy => true
end
class Entry < ActiveRecord::Base
belongs_to :user
has_many :entry_ingredients
has_many :ingredients, :through => :entry_ingredients
has_many :steps
accepts_nested_attributes_for :entry_ingredients, :allow_destroy => true
accepts_nested_attributes_for :steps, :reject_if => lambda { |s| s[:description].blank? }, :allow_destroy => true
end
MISE À JOUR:
trouveurs dynamiques sonores comme ils le font ce que je veux, en particulier find_or_create
ou first_or_create
mais je ne suis pas en mesure de comprendre comment les utiliser dans ma configuration. Quelqu'un peut-il me pousser dans la bonne direction ici? Voilà ce que j'ai essayé, mais je me rends compte que cela est tout simplement de créer un nouvel ingrédient à chaque fois que les entrées # nouvelles est appelé ... pas ce que je veux arriver
#entries_controller.rb
def new
@entry = Entry.new
@entry.entry_ingredients.build.build_ingredient
@entry.steps.build
@ingredient = Ingredient.where(params[:ingredient]).first_or_create()
respond_to do |format|
format.html # new.html.erb
format.xml { render :xml => @entry }
end
end
#_entry_ingredient_fields.html.erb
<%= f.fields_for :ingredient do |builder| %>
<%= builder.label :name %>
<%= builder.text_field :name, :class => "ingredient_field" %>
<% end %>
Examinez une solution de saisie semi-automatique lors de l'ajout d'ingrédients. ajouter également une validation de l'unicité au nom des ingrédients pour au moins éviter la duplication basée sur les noms. – jvnill
mais si j'ajoute la validation de l'unicité, un utilisateur obtiendrait une erreur lors de la sauvegarde d'un ingrédient qui existe déjà ... peut-être que je suis supposé en utiliser un au lieu d'en avoir plusieurs? Je vais poster mes modèles maintenant. – GiH
avec une solution de saisie semi-automatique en place, vous n'avez pas à vous soucier d'échouer à la validation de l'unicité. c'est juste là, donc vous n'aurez pas de doublons dans le db. si elle existe déjà dans la base de données, la fonctionnalité de saisie semi-automatique doit être utilisée. Si ce n'est pas le cas, un champ de texte libre peut être ajouté pour créer un nouvel ingrédient. – jvnill