-
Notifications
You must be signed in to change notification settings - Fork 161
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support for custom object evaluation #227
Comments
I would approach this by figuring out a way to transform your objects into hashes, and then pass those in as the context data for your formulas. If these are something like ActiveRecord or ActiveModel objects, then you can probably use module Hashify
def hashify
instance_variables.each_with_object({}) do |var, h|
key = var.to_s[1..] # transform :@var into "var"
value = instance_variable_get(var)
h[key] = value.respond_to?(:hashify) ? value.hashify : value
end
end
end
class User
include Hashify
attr_reader :age, :profile
def initialize(age, profile)
@age = age
@profile = profile
end
end
class Profile
include Hashify
attr_reader :favorite_color
def initialize(favorite_color)
@favorite_color = favorite_color
end
end
user = User.new(21, Profile.new("red"))
Dentaku("user.age >= 18 AND user.profile.favorite_color = 'red'", user: user.hashify)
# => true |
Thanks for the reply! We looked at hashing, but unfortunately all of the fields need to be lazy-loaded. We have hundreds of calculated value methods used in these templates, and in aggregate would be way too slow. Generating a full hash for just one object could take 10+ seconds, and in many cases dozens of objects are used in one template. If supporting dot notation is not a good fit, another solution that could work is making it possible to override/subclass variable lookup. Something like: class CustomVariableLookup < DentakuLookup
def initialize(context)
@context = context
end
def value(name)
# look up name and method availability (split on first dots?)
if found
result
else
super
end
end
end
calculator = Dentaku::Calculator.new(lookup: CustomVariableLookup.new(our_context)) |
Ah, sorry -- I guess that's what you meant by "it wouldn't be practical to generate them all". 😆 Currently Dentaku eagerly flattens hash values into dot-separated keys when storing things in memory by default, but you can disable this by setting As a temporary workaround, would it be feasible to make the "hashify" code a little smarter so that you could feed in just the values you need flattened? If so, you could parse a formula, get the unbound variables needed to evaluate it and then feed that to hashify to get just the data you need. |
I pushed up a lazy-resolver branch, can you take a look and see if this would work for your use case? (updated to fix branch reference) 😊 |
Hi! 👋 This gem looks awesome, thanks for making it. It's a perfect fit for some needs we have to do simple user template evaluation to generate documents. Our use case includes object evaluation, though, and I couldn't see a way for it to work with dentaku. For example,
"user.age >= 18
, whereuser
is a simple class like this:I tried doing something like
We managed to make it work by adding a string representing the object chain...
...but we have hundreds of variations and nestings we'd have to support (like
user.profile.default_value
) and it wouldn't be practical to generate them all.Is there a mechanism that would allow for the dot chain evaluation that I missed, maybe some kind of custom evaluator? If not, do you think it would be feasible to add?
(We can also pre-evaluate the values into a string, and then use Dentaku to calculate the final results, but that would unfortunately require a large refactor of our parser and generator, so this seems like the simplest route to start).
Thanks!
The text was updated successfully, but these errors were encountered: