将文本转换为代码

时间:2011-01-30 14:14:45

标签: ruby-on-rails ruby-on-rails-3 workflow

我正在创建产品配置器。麻烦的是每个产品都有许多组件,这些组件本身是可配置的。想象一下,您在购买时正在配置计算机。 当选择组件时,或者当组件的数量,或者甚至是两者的组合时,依赖性有时适用。这一切在某些方面变得非常复杂,并且在产品之间并不一致,因为在某种意义上每个都是它自己的宇宙。

哦,这些规则一直在变化,所以在应用程序中对它们进行编码对我来说不是一个真正的选择。

我希望能够在数据库中存储名为validate的方法的代码。 每个配置都有自己的validate版本,它将作为文本存储在db中,并且可以在需要时进行更改。

可以这样做吗?如何使用文本并让rails实际执行此文本所说的内容?

例如我有这个:

irb(main):246:0> @h= Configuration.find(1).rule
=> "def getmax3(inputarray)\n    @maxpos = 0\n    inputarray.each do |h|\n      if @maxpos < h.position\n      @maxpos = h.position\n      end\n    end\n    1\n end"

显然不是代码。上面的方法当然只是一个测试,因为我正试图解决问题。

(哦,我知道做这件事一定是可怕的做法,但我真的想不出另一种方式)

非常感谢!

2 个答案:

答案 0 :(得分:1)

是的,这是一种可怕的做法:)

如果要实现简单且稳定的规则,可以将某些变量存储在专用表中,并在规则中使用这些变量;因为看起来你真的不知道这些规则会发生什么,所以准备好接受任何挑战,使用经过测试和验证的工作流程。

这是我的建议:

  • 使用capistrano和其他工具设置自动部署过程
  • 在专用验证库中编写规则
  • 代码&amp;测试规则,提交和部署

定义DSL可以让您的生活更轻松,如果您长期致力于操纵此类规则,并且您不可能是唯一负责此类任务的人;观察规则如何在很长一段时间内改变,你会知道拥有专用的DSL是好事还是浪费时间。

答案 1 :(得分:1)

我可能误解了你的问题,但是如果你能从数据库中获取该代码并将其转换为可以测试和版本化的文件,那么你将会处于一个更加快乐的地方。如果不知道模型的复杂性,很难说最好的方法是什么,但我保证一个就在那里。

我过去曾使用单表继承来建模具有共享公共属性和行为的相关组件的复杂系统。您可以在应用程序中使用此方法。 STI基本上说你有一个父类,在你的情况下,配置和子类,都在同一个表中。如果某些子类之间存在共享行为,那么您可以将该代码移动到模块并包含在需要它的类中。

基本父类只会从ActiveRecord继承:

class Configuration < ActiveRecord::Base
end

然后每个子类都将在其中定义其逻辑:

class Component < Configuration
  def getmax3(inputarray)
    @maxpos = 0
    inputarray.each do |h|
      if @maxpos < h.position
        @maxpos = h.position
      end
    end
    1
  end
end

我不是说这是你想要的方向,但希望它会让你考虑其他的系统建模方法。