2008-09-21 9 views
0

J'ai un modèle de rails qui ressemble à ceci:Comment enregistrer un modèle avec ce champ généré dynamiquement?

class Recipe < ActiveRecord::Base 
    has_many :ingredients 
    attr_accessor :ingredients_string 
    attr_accessible :title, :directions, :ingredients, :ingredients_string 

    before_save :set_ingredients 

    def ingredients_string 
     ingredients.join("\n") 
    end 

    private 

    def set_ingredients 
     self.ingredients.each { |x| x.destroy } 
     self.ingredients_string ||= false 
     if self.ingredients_string 
     self.ingredients_string.split("\n").each do |x| 
      ingredient = Ingredient.create(:ingredient_string => x) 
      self.ingredients << ingredient 
     end 
     end 
    end 
end 

L'idée est que lorsque je crée l'ingrédient de la page Web, je passe dans le ingredients_string et laisser le genre de modèle tout ça. Bien sûr, si je suis en train d'éditer un ingrédient, j'ai besoin de recréer cette chaîne. Le bug est fondamentalement ceci: comment est-ce que j'informe la vue de l'ingrédient_string (élégamment) et vérifie toujours si le ingredient_string est défini dans la méthode set_ingredients?

+0

Je suis désolé, je ne comprends pas vraiment ce que vous demandez. Quel est le problème que vous essayez de résoudre? Pouvez-vous donner un exemple de la façon dont il est utilisé et où il tombe en panne? – bhollis

Répondre

0

L'utilisation conjointe de ces deux causes est probablement à l'origine de vos problèmes. Les deux tentent de définir une méthode ingredients_string qui font des choses différentes

attr_accessor :ingredients_string 

    def ingredients_string 
     ingredients.join("\n") 
    end 

se débarrasser de la attr_accessor, la méthode before_save, set_ingredients et définir votre propre méthode ingredients_string=, quelque chose comme ceci:

def ingredients_string=(ingredients) 
    ingredients.each { |x| x.destroy } 
    ingredients_string ||= false 
    if ingredients_string 
     ingredients_string.split("\n").each do |x| 
      ingredient = Ingredient.create(:ingredient_string => x) 
      self.ingredients << ingredient 
     end 
    end 
end 

note I juste emprunté votre mise en œuvre de set_ingredients. Il y a probablement une façon plus élégante de rompre cette chaîne et de créer/supprimer des associations de modèles d'Ingrédients selon les besoins, mais il est tard et je ne peux pas y penser maintenant. :)

0

La réponse précédente est très bonne mais elle pourrait faire avec quelques changements.

def ingrédients_string = (texte) ingredients.each {| x | x.destroy} sauf text.blank? Text.split ("\ n"). Each do | x | ingrédient = Ingredient.find_or_create_by_ingredient_string (: ingredient_string => x) self.ingredients
+0

Eh bien, ce n'est pas vraiment une situation find_or_create_by. Les ingrédients sont uniques. IngredientTypes, otoh, ne sont pas uniques et sont configurés avec une méthode find_or_create_by. Merci quand même! –

0

Je fondamentalement juste modifié la réponse d'Otto:

class Recipe < ActiveRecord::Base 
    has_many :ingredients 
    attr_accessible :title, :directions, :ingredients, :ingredients_string 

    def ingredients_string=(ingredient_string) 
     ingredient_string ||= false 
     if ingredient_string 
     self.ingredients.each { |x| x.destroy } 
     unless ingredient_string.blank? 
      ingredient_string.split("\n").each do |x| 
       ingredient = Ingredient.create(:ingredient_string => x) 
       self.ingredients << ingredient 
      end 
     end 
     end 
    end 

    def ingredients_string 
     ingredients.join("\n") 
    end 

end 
Questions connexes