Ruby on rails 保存基于ruby代码更改的属性

Ruby on rails 保存基于ruby代码更改的属性,ruby-on-rails,ruby,ruby-on-rails-3,Ruby On Rails,Ruby,Ruby On Rails 3,我有一个模块需要保存一个解决方案(用于测验)值。当然,当解决方案只是一个像“342”这样的值时,这是微不足道的。但是,在某些情况下,会进行一些动态计算。例如,如果用户输入值100,可能是为了得到正确的解,我首先必须计算(x*2)==300。因此,如果x=100,则解决方案将是错误的 不幸的是,我无法将此类计算存储在数据库中(至少根据我所知)。我可以做的一件事是为我的测验模型中的特定测验添加特定的解决方法。然而,我一点也不喜欢这样。这使得课堂很难维持,所以我很快就放弃了这个想法 另一个想法是在每个

我有一个模块需要保存一个解决方案(用于测验)值。当然,当解决方案只是一个像“342”这样的值时,这是微不足道的。但是,在某些情况下,会进行一些动态计算。例如,如果用户输入值100,可能是为了得到正确的解,我首先必须计算(x*2)==300。因此,如果x=100,则解决方案将是错误的

不幸的是,我无法将此类计算存储在数据库中(至少根据我所知)。我可以做的一件事是为我的测验模型中的特定测验添加特定的解决方法。然而,我一点也不喜欢这样。这使得课堂很难维持,所以我很快就放弃了这个想法

另一个想法是在每个需要的测验中保存一个新的类对象。这个类将包含所有需要的方法,这些方法只是验证计算(使用STI或模块,后者很可能更容易)。我更喜欢这个想法,我认为这很可能是我要实施的,但在这样做之前,我想听听你对它的想法

你会怎么做

请注意,创建一个模块或类来处理所有解决方案会产生一个大问题,我希望将来有多个测验作者。如果他们能够创造自己的挑战,那么以这种方式为他们创造动态解决方案几乎是不可能的。或者,如果我监督每一个这样的条目并手动创建所需的代码,那将是一个地狱

我无法将此类计算存储在数据库中(至少根据我所知)

当然可以。代码只是文本,ruby是一种动态语言。您可以将正确的解决方案计算表达式存储为文本,然后使用eval将其转换为代码

因此,如果该文本字段是包含类似“(x.to_i*2)==300”(期望x是提供的答案)的问题对象的求值表达式字段:

这使您能够使用任意复杂的ruby表达式来计算测验问题的正确答案,并将其存储在数据库中


不幸的是,如果您接受不受信任的用户输入这些表达式,这也是一个安全风险,因为您将在您的服务中执行他们输入的ruby。当然,如果多个测试作者必须编写代码来表达他们的问题,这是一个常见的问题。

将Ruby代码作为文本存储在数据库中,并在
eval
评估它之前对其运行解析器(以确认它只包含一个算术表达式,而不是像
Dir['/***']这样的讨厌的东西。每个{f | File.delete(f)}
)。您可以使用Treetop之类的工具来构建解析器。作为奖励,一旦您知道如何使用Treetop,下次您需要构建解析器时,就很容易了。

这就是我所说的“不能”。存储这样的表达式并直接执行它们太危险了。但是thanx的想法是:)啊,这一点都不清楚。不管怎样,如果你想要安全,按照AlexD的建议,解析一种最小的语言,它没有做破坏性事情的能力。从解析器可以更好地消除安全威胁的意义上来说,这可能是很好的。有意思,我来看看
evaluator = eval "lambda { |x| #{question.evaluation_expr} }"
got_it_right = evaluator.call( params[:x] )