Skip to content

Instantly share code, notes, and snippets.

@amkisko
Last active May 6, 2025 14:58
Show Gist options
  • Save amkisko/0c5e7ed2d76dd28abff933467ca40bd9 to your computer and use it in GitHub Desktop.
Save amkisko/0c5e7ed2d76dd28abff933467ca40bd9 to your computer and use it in GitHub Desktop.
Calculatable attributes concern for ActiveRecord models
module CalculatableAttributes
extend ActiveSupport::Concern
class_methods do
def calculate(attribute, calculator = nil, column_name: nil, only_cache_on_read: false, &block)
attr_name = attribute.to_s.delete("?")
column_name ||= attr_name
attr_calculator = calculator || block
@@calculate_methods ||= {}
@@calculate_methods[name] ||= {}
@@calculate_methods[name][attr_name] = attr_calculator
define_method(:"calculate_#{attr_name}") do
instance_exec(&attr_calculator)
end
define_method(:"calculate_#{attr_name}!") do
assign_attributes(column_name => method(:"calculate_#{attr_name}").call)
end
define_method(attribute) do
return attributes[column_name] if only_cache_on_read
attributes[column_name] || method(:"calculate_#{attr_name}").call
end
unless method_defined?(:calculate!)
define_method(:calculate!) do
@@calculate_methods[name].keys.each do |attr_name|
method(:"calculate_#{attr_name}!").call
end
end
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment