在db中保存Duration对象(然后是eval())的字符串表示是不好的做法吗?

时间:2012-02-24 17:06:02

标签: ruby-on-rails

我正在开发具有一些预算功能的Rails应用程序......

我想要做的是允许用户创建Budget并指定开始日期和间隔(例如"每月","季度",&#34 ;每年"等)。从那以后我就不建立BudgetPeriod,第一个从给定的开始日期开始,并且是#34; interval"长。下一个时期从前一个结束开始,所以它应该随着时间的推移而继续......

我想出的一个简单的解决方案是将间隔保存为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 个答案:

答案 0 :(得分:1)

坏了!如果可以帮助它,请尽量不要评估,如果使用不当,可能会造成极大的破坏性。

如果您想这样做,最好将您尝试存储的内容转储到数据库中,然后再将其删除:

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

...

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

如果间隔总是像这样从数据库中转储出来,Rails会提供一种称为序列化的方便方法来自动执行此操作,因此您只需在模型中执行此操作:

serialize :interval

然后当你执行self.interval = 3.months时,你可以保证只将Ruby对象从数据库中取出,不需要eval。