Ruby on rails ActiveRecord对象的静态实现
所以我有一组奇怪的情况,基本上需要一个静态实现附加到活动记录对象。以下是背景 我有一个Ruby on rails ActiveRecord对象的静态实现,ruby-on-rails,ruby,ruby-on-rails-5,Ruby On Rails,Ruby,Ruby On Rails 5,所以我有一组奇怪的情况,基本上需要一个静态实现附加到活动记录对象。以下是背景 我有一个产品,由一个或多个提供商(有多个:产品提供商)。但是,每个提供商都有一套基于请求表单的特定产品费率,包括唯一费率(美元金额)和算法。由于算法的复杂性,它们存储在单独的Ruby类中 我试图完成的是如何将ProductProvider与静态类关联起来。我的第一次实施大致如下: # slug = 'acme-widget' slug.split('-').join('/').camelize.constantize
产品
,由一个或多个提供商
(有多个:产品提供商
)。但是,每个提供商
都有一套基于请求表单的特定产品
费率,包括唯一费率(美元金额)和算法。由于算法的复杂性,它们存储在单独的Ruby类中
我试图完成的是如何将ProductProvider
与静态类关联起来。我的第一次实施大致如下:
# slug = 'acme-widget'
slug.split('-').join('/').camelize.constantize
这将给我一个类,
Acme::Widget
。这在技术上是可行的,但我觉得一定有更好的模式。我以前使用gem解决了这个(总体)问题:它负责从数据库存储值获取正确的类实例,并带来了一些其他枚举便利
然而,自从我上次使用它已经有一段时间了,宝石现在是。虽然它仍然适合您的问题,但可能需要一些更新才能与Rails 5.0+一起使用
如果您要自己实现它,在可能受用户影响的输入上调用
constantize
时要小心。静态散列是最安全的;作用域const_-get
ProviderStrategy.const_-get
,或限制字符串上的constantize
(“Provider::{s})。constantize
),是次优选择
这一点很重要,因为如果[恶意]用户能够在运行的系统中选择任意常量,通常在无法响应所需方法时会出错,但是。一般来说,这种方法似乎足够好。稍微短一点的是
slug.gsub('-','/').camelize.constantize
。或者,我想您可以创建一个自定义屈折。您有多少个这样的静态类?如果您只有少数Acme::Widget
-类型,那么将它们映射到哈希{'Acme-Widget'=>Acme::Widget}
可能会更快(更安全),目前大约有63个ProductProviders。所以这不是一个小数目。输入主要来自种子,slug是只读的。所以我并不担心用户输入带来的灾难。看起来这可能是我没有看到的一种常见模式。非常感谢。