Skip to content

Instantly share code, notes, and snippets.

@we4tech
Created December 30, 2013 08:39
Show Gist options
  • Save we4tech/8179459 to your computer and use it in GitHub Desktop.
Save we4tech/8179459 to your computer and use it in GitHub Desktop.
Define attribute which value is loaded and stored lazily. Ie. You want to get some data from a 3rd party API call but instead of setting them explicitly you want to get those on demand. Here are few lines of code to get it workable.
module Concerns
module LazyAttribute
extend ActiveSupport::Concern
included do
class_attribute :lazy_attributes
end
module ClassMethods
def attr_lazy(name, &logic_impl)
sym = name.to_sym
self.lazy_attributes ||= {}
self.lazy_attributes[sym] = logic_impl
create_lazy_getter(sym)
end
def create_lazy_getter(name)
class_eval <<-CODE, __FILE__, __LINE__
def #{name}
val = self.read_attribute(:#{name})
return val if val.present?
logic = self.lazy_attributes[:#{name}]
val = self.instance_eval &logic
self.update_column :#{name}, val if val
val
end
CODE
end
end
end
end
class SomeModel < ActiveRecord::Base
include Concerns::LazyAttribute
attr_lazy :some_data do
# Do some expensive API call or calculation or whatever make sense to you.
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment