因此,我遇到了一些奇怪的情况,基本上需要一个附加到Active Record对象的静态实现。这是背景。
我有一个Product
,由一个或多个Provider
(has_many_through :product_providers
)出售。但是,每个Provider
都基于请求表为每个Product
设置一组特定的费率,包括唯一费率(美元)和算法。由于算法的复杂性,它们存储在单独的Ruby类中。
我要完成的工作是如何将ProductProvider
与静态类相关联。我的第一个实现是按照以下方式进行的:
# slug = 'acme-widget'
slug.split('-').join('/').camelize.constantize
这将给我Acme::Widget
类。从技术上讲这是可行的,但我觉得必须有一个更好的模式。
答案 0 :(得分:1)
我以前已经使用classy_enum gem解决了这个(总体)问题:它负责从数据库存储的值获取正确的类实例,并带来了其他枚举的便利。
但是,自上次使用以来已经有一段时间了,现在的宝石是no longer actively maintained。尽管它仍然很适合您的问题,但可能需要一些更新才能与Rails 5.0+一起使用。
如果您要自己实现,请在可能受到用户影响的输入上调用constantize
时要小心。静态哈希是最安全的;其次是限定范围的const_get
ProviderStrategy.const_get(s)
或受限字符串(constantize
上的"Provider::#{s}".constantize
。
这很重要,因为如果[恶意的]用户能够在运行的系统中选择任意常量,则当它无法响应所需的方法时,它将通常只是错误,但是{{ 3}}。