Сохранить атрибут, который изменяется на основе кода ruby - PullRequest
1 голос
/ 12 марта 2012

У меня есть модуль, который должен сохранить значение решения (для теста).Это, конечно, тривиально, когда решением является просто значение типа «342».Однако есть случаи, когда происходят динамические вычисления.Например, если пользователь вводит значение 100, возможно, для того, чтобы получить правильное решение, я сначала должен рассчитать (x * 2) == 300. Поэтому, если x = 100, решение будет неправильным.

К сожалению, я не могу хранить такие вычисления в базе данных (по крайней мере, основываясь на том, что я знаю).Одна вещь, которую я мог бы сделать, это добавить конкретные методы решения для конкретных тестов в моей модели Викторины.Однако мне это совсем не нравится.Это делает класс очень сложным в обслуживании, поэтому я быстро отказался от этой идеи.

Другая идея состояла бы в том, чтобы сохранять новый объект класса в каждом тесте, в котором это необходимо.Этот класс будет включать все необходимые методы, которые просто проверяют вычисления (либо с STI, либо с модулем, скорее всего, последний проще).Мне больше нравится эта идея, и я думаю, что, скорее всего, это то, что я собираюсь реализовать, но прежде чем сделать это, я хотел бы услышать ваши идеи по этому поводу.

Как бы вы поступили об этом?

ОБРАТИТЕ ВНИМАНИЕ, что большая проблема, которая возникает из-за создания модуля или класса для обработки всех решений, это тот случай, когда я хотел бы иметь несколько авторов викторин в будущем.Если бы они могли создавать свои собственные проблемы, было бы практически невозможно создать для них динамические решения.Или это был бы ад для меня, чтобы контролировать каждую такую ​​запись и вручную создавать необходимый код.

Ответы [ 2 ]

1 голос
/ 12 марта 2012

Сохраните код Ruby в своей БД в виде текста и запустите анализатор над ним до eval его использования (чтобы убедиться, что он содержит только арифметическое выражение, а не что-то неприятное, например Dir['/**/*'].each { |f| File.delete(f) }). Вы можете использовать такой инструмент, как Treetop, для создания парсера. В качестве бонуса, если вы знаете, как использовать Treetop, в следующий раз вам нужно будет создать парсер, это будет легко.

1 голос
/ 12 марта 2012

я не могу хранить такие вычисления в базе данных (по крайней мере, основываясь на том, что я знаю)

Конечно, вы можете. Код - это просто текст, а ruby ​​- динамический язык. Вы можете сохранить правильное выражение оценки решения в виде текста, а затем превратить его в код с помощью eval.

Итак, если это текстовое поле было полемvaluation_expr объекта вопроса, содержащего что-то вроде "(x.to_i * 2) == 300" (ожидая, что x будет предоставленным ответом):

evaluator = eval "lambda { |x| #{question.evaluation_expr} }"
got_it_right = evaluator.call( params[:x] )

Это дает вам возможность иметь произвольно сложные рубиновые выражения для вычисления правильных ответов на ваш вопрос викторины и сохранять их в базе данных.

К сожалению, это также угроза безопасности, если вы принимаете ввод этих выражений от ненадежных пользователей, потому что вы собираетесь выполнить то, что они вводят как ruby ​​в вашем сервисе. Конечно, эта проблема присуща нескольким авторам викторин, если им приходится писать код для выражения своих вопросов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...