【问题标题】:rails model templates (or instance inheritance) options?rails 模型模板(或实例继承)选项?
【发布时间】:2010-11-21 20:09:20
【问题描述】:

我有一种情况,我想在 Rails 中制作“参数”模型;例如我想定义PrototypeRecipe,然后能够创建多个DerivedRecipe;也许一种衍生配方使用更多的糖,而另一种使用更少的鸡蛋或其他东西。关键点是我希望所有“派生”实例都从单个共享 PrototypeRecipe 继承属性,但能够进行本地修改。

理想情况下,我希望能够在原型上定义方法(例如,将购物清单放在一起),并让这些方法响应派生实例中的本地更改(因此,如果我指定 3 个鸡蛋而不是 2 个,我可以调用原型的make_shopping_list 函数,它会反映这一点)。

是否有现有的方法来完成这样的事情?这是迄今为止我能想到的最好的:

class Ingredient << ActiveRecord::Base
    belongs_to :recipe, :polymorphic => true

    # uuid => UUID String (for grouping ingredients which change between prototype and derived instances)
end

class PrototypeRecipe << ActiveRecord::Base
    has_many :ingredients

    def make_ingredient_list(derived_recipe = nil)
        self.ingredients.map {|i| derived_recipe.nil? ? i : derived_recipe.ingredients.where(:ingredient_uuid => i.uuid).first }
    end
end

class DerivedRecipe << ActiveRecord::Base
    belongs_to :prototype_recipe

    has_many :ingredients

    def method_missing(sym, *args)
        self.prototype_recipe.send( sym, *args, self)
    end
end

我知道这段代码可以变得更简洁,我更想知道是否可以改进一般方法。基本思想是每种成分都有一个唯一的 ID。要修改原型配方,您只需创建DerivedRecipe 的实例,将其链接到原型,然后添加与原型成分之一具有相同 UUID 的成分。

【问题讨论】:

    标签: ruby-on-rails inheritance prototype


    【解决方案1】:

    我不是 100% 你希望有什么行为,所以这是我尝试的解决方案。

    单表继承 (STI)。你的基类是PrototypeRecipe,你的子类是DerivedRecipe

    prototype_recipes 表中,指定type 列(文本)。这向 Rails 发出您想要使用 STI 的信号。如果您将 make_ingredients_list 方法放在基类中,则可以从您的子类中访问它。

    # app/models/ingredient.rb
    class Ingredient < ActiveRecord::Base
      belongs_to :recipe, :class_name => "PrototypeRecipe"
      ...
    end
    
    # app/models/prototype_recipe.rb
    class PrototypeRecipe < ActiveRecord::Base
      has_many :ingredients
      has_many :derived_recipes
    
      def make_ingredient_list
        ...
      end
    end
    
    # app/models/derived_recipe.rb
    class DerivedRecipe < PrototypeRecipe
      belongs_to :prototype_recipe
    end
    

    现在您可以执行以下操作:

    @cupcakes = PrototypeRecipe.create
    @cupcakes_with_extra_eggs = @cupcakes.derived_recipes.create
    print @cupcakes_with_extra_eggs.make_ingredient_list
    

    这是你要找的吗?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-01-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多