Convert text into code
I'm in the process of creating a product configurator. Trouble is that each product has many components, which are themselves configurable. Imagine you're configuring a computer when buying it. The dependencies sometimes apply when a component is selected, or when a quantity of a component, or even a combination of both. It all becomes very complicated at some poi开发者_C百科nt, and is not consistent across products, as each is its own universe in a sense.
Oh, and these rules change all the time, so coding them in the app is not really an option for me.
I was hoping to be able to store the code of a method called validate in the database. Each configuration would have it's own version of validate, which would be stored as a text in the db, and could be changed if/when required.
Is is possible to do this? How can i take text and have rails actually execute whatever this text says?
For example i have this:
irb(main):246:0> @h= Configuration.find(1).rule
=> "def getmax3(inputarray)\n @maxpos = 0\n inputarray.each do |h|\n if @maxpos < h.position\n @maxpos = h.position\n end\n end\n 1\n end"
which obviosly isn't code. The method above is of course just a test as I'm trying to figure things out.
(Oh and I know it must be horrible practice to do this, but I really can't think of another way)
Thanks a lot!
Yes it is an horrible practice :)
If you had simple and stabilized rules to implement, you could store some variables in a dedicated table and use those variables in your rules; since it looks like you don't really know what is going to happen about those rules, be ready to accept any challenge by using a tested and proven workflow.
Here's my suggestion:
- Setup an automatic deploy procedure using capistrano and other tools
- Write your rules in a dedicated validation library
- Code & test rules, commit and deploy
Defining a DSL can make your life easier, if you are committed in the long term to manipulate such rules and you could not be the only one in charge of such task; observe how the rules are changed over a good amount of time and you will know if having a dedicated DSL is a good thing or a waste of time.
I might be misunderstanding your problem, but if you could get that code out of the database and into files that can be tested and versioned, you'll be in a much happier place. Without knowing the intricacies of your models, it's hard to say what the best approach would be, but I guarantee one is out there.
I've used Single Table Inheritance in the past for modeling complex systems that have related components which share common properties and behavior. You might be able to use this approach with your application. STI basically says you have a parent class, in your case Configuration, and subclasses, that all reside in the same table. If there is shared behavior among some but not all of the subclasses, then you can move that code to modules and include in the classes that need it.
Basic parent class would just inherit from ActiveRecord:
class Configuration < ActiveRecord::Base
end
Then each subclass would have its logic defined within it:
class Component < Configuration
def getmax3(inputarray)
@maxpos = 0
inputarray.each do |h|
if @maxpos < h.position
@maxpos = h.position
end
end
1
end
end
I'm not saying this is the direction you want to go, but hopefully it will make you think about other ways of modeling your system.
精彩评论