ActiveRecord对象的静态实现

时间:2018-07-26 20:16:52

标签: ruby-on-rails ruby ruby-on-rails-5

因此,我遇到了一些奇怪的情况,基本上需要一个附加到Active Record对象的静态实现。这是背景。

我有一个Product,由一个或多个Providerhas_many_through :product_providers)出售。但是,每个Provider都基于请求表为每个Product设置一组特定的费率,包括唯一费率(美元)和算法。由于算法的复杂性,它们存储在单独的Ruby类中。

我要完成的工作是如何将ProductProvider与静态类相关联。我的第一个实现是按照以下方式进行的:

# slug = 'acme-widget'
slug.split('-').join('/').camelize.constantize

这将给我Acme::Widget类。从技术上讲这是可行的,但我觉得必须有一个更好的模式。

1 个答案:

答案 0 :(得分:1)

我以前已经使用classy_enum gem解决了这个(总体)问题:它负责从数据库存储的值获取正确的类实例,并带来了其他枚举的便利。

但是,自上次使用以来已经有一段时间了,现在的宝石是no longer actively maintained。尽管它仍然很适合您的问题,但可能需要一些更新才能与Rails 5.0+一起使用。


如果您要自己实现,请在可能受到用户影响的输入上调用constantize时要小心。静态哈希是最安全的;其次是限定范围的const_get ProviderStrategy.const_get(s)或受限字符串(constantize上的"Provider::#{s}".constantize

这很重要,因为如果[恶意的]用户能够在运行的系统中选择任意常量,则当它无法响应所需的方法时,它将通常只是错误,但是{{ 3}}。