Jack M.
Jack M.

Reputation: 32070

Static implementation on ActiveRecord object

So I have an odd set of circumstances, which basically requires a static implementation attached to an Active Record object. Here is the background.

I have a Product, which is sold by one or more Provider (has_many_through :product_providers). However, each Provider has a specific set of rates for each Product based on a request form, consisting of unique rates (dollar amounts) and algorithms. Due to the complexity of the algorithms, they are stored in separate Ruby classes.

What I'm trying to accomplish is how to associate a ProductProvider with a static class. My first implementation was something along the lines of:

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

This would give me the class, Acme::Widget. This technically works, but I feel like there must be a better pattern.

Upvotes: 1

Views: 228

Answers (1)

matthewd
matthewd

Reputation: 4420

I've previously solved this (overall) problem using the classy_enum gem: it takes care of getting from the database-stored value to the right class instance, and brings some other enum conveniences along for the ride.

However, it's been some time since I last used it, and the gem is now no longer actively maintained. While it would still be a good fit for your problem, it might need some updates to work with Rails 5.0+.


If you're going to implement it yourself, be careful when calling constantize on possibly-user-affected input. A static hash would be safest; a scoped const_get ProviderStrategy.const_get(s), or a constantize on a restricted string ("Provider::#{s}".constantize), is next best.

This is important because if a [malicious] user is able to choose an arbitrary constant in the running system, it will generally just error when it fails to respond to a required method, but there are always tricky edge cases.

Upvotes: 1

Related Questions