Created
December 30, 2013 08:39
-
-
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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