Плохо ли сохранять строковые представления объектов Duration (а затем и eval ()) в БД? - PullRequest
0 голосов
/ 24 февраля 2012

Я работаю над приложением Rails с некоторыми бюджетными функциями ...

Я хочу разрешить пользователям создавать Budget и указывать дату начала и интервал (например, «Ежемесячно»)."," Ежеквартально "," Ежегодно "и т. Д.).Из этого я не хочу строить BudgetPeriod, первый из которых начинается с заданной даты начала и имеет длительность "интервала".Следующий период начинается там, где заканчивается предыдущий, и поэтому он должен продолжаться с течением времени ...

Простое решение, которое я нашел для этого, состояло в том, чтобы сохранить интервалы в виде строковых представлений объектов Duration, поэтомуЕжемесячно будет "1.month" и ежеквартально "3.months".А затем используйте eval(interval), чтобы вычислить даты начала и окончания периодов, как это

after_create :create_periods
def create_periods
  period_start = self.starting_at
  while period_start <= Date.today
    next_start = period_start + eval(self.interval)
    period_end = next_start - 1.day
    budget_periods.create(start_date: period_start, end_date: period_end)
    period_start = next_start
  end
end

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

Итак, это плохая практика или я должен продолжать?

1 Ответ

1 голос
/ 24 февраля 2012

Плохо! Старайтесь не оценивать, если вы можете помочь, это может быть невероятно разрушительным при неправильном использовании.

Если вы хотите сделать это, было бы лучше выгрузить то, что вы пытаетесь сохранить в базу данных, а затем снова вывести это:

self.interval = Marshal.dump(3.months)

...

next_start = period_start + Marshal.load(self.interval)

Если интервал всегда будет сбрасываться в и из базы данных, как это, Rails предлагает удобный метод, называемый serialize, чтобы сделать это автоматически для вас, поэтому вам нужно будет сделать это только в вашей модели:

serialize :interval

Затем, когда вы сделаете self.interval = 3.months, вы гарантированно получите только этот объект Ruby из вашей базы данных, никакого eval не требуется.

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