如何使用此动态生成的字段保存模型?

时间:2008-09-21 03:28:30

标签: ruby-on-rails

我有一个看起来像这样的rails模型:

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

我的想法是,当我从网页创建成分时,我传入ingredients_string并让模型对其进行排序。当然,如果我正在编辑一种成分,我需要重新创建该字符串。该错误基本上是这样的:如何通知ideal_string的视图(优雅地)并仍然检查ingredient_string方法中是否定义了set_ingredients

3 个答案:

答案 0 :(得分:0)

将这两者结合使用可能会导致您的问题。两者都试图定义一个做不同事情的ingredients_string方法

   attr_accessor :ingredients_string

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

摆脱attr_accessorbefore_saveset_ingredients方法并定义自己的ingredients_string=方法,如下所示:

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

注意我刚刚借用了set_ingredients的实现。可能有一种更优雅的方式来分解该字符串并根据需要创建/删除成分模型关联,但现在已经很晚了,我无法想到它。 :)

答案 1 :(得分:0)

之前的答案非常好,但可以做一些改变。

def ingredients_string =(text)     ingredients.each {| x | x.destroy}     除非text.blank?         text.split(“\ n”)。每个都执行| x |             成分= Ingredient.find_or_create_by_ingredient_string(:ingredient_string =&gt; x)             self.ingredients

答案 2 :(得分:0)

我基本上只修改了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