Skip to content

Instantly share code, notes, and snippets.

Created July 8, 2016 09:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/7d972a7e8aa1187fc59a53a26746962d to your computer and use it in GitHub Desktop.
Save anonymous/7d972a7e8aa1187fc59a53a26746962d to your computer and use it in GitHub Desktop.
module WithAssociation
def self.included(base)
base.extend(ClassMethods)
end
module ClassMethods
def belongs_to(key, opts = {})
column = "#{key}_id" #opts[:foreign_key] || "#{key}_id"
id_writer = "#{column}=".to_sym
id_reader = "#{column}".to_sym
obj_reader = key
obj_writer = "#{key}=".to_sym
attr_key = key
obj_class = opts[:class] || opts[:class_name].try(&:constantize) || key.to_s.camelcase.constantize
define_method("attr_") do
@attr_ ||= {}
end
define_method("attr_cached_") do
@attr_cached_ ||= {}
end
define_method(obj_reader) do
obj_id = self.attr_[attr_key]
return nil if obj_id.nil?
cached = self.attr_cached_[attr_key]
if cached.nil?
cached = self.attr_cached_[attr_key] = obj_class.find(self.attr_[attr_key])
end
return cached
end
define_method(obj_writer) do |obj|
if obj.nil?
invalidate_cached_(attr_key)
self.attr_.delete(attr_key)
else
self.attr_[attr_key] = obj.id
self.attr_cached_[attr_key] = obj
end
end
define_method(id_reader) do
self.attr_[attr_key]
end
define_method(id_writer) do |obj|
self.attr_[attr_key] = obj
invalidate_cached_(attr_key)
end
define_method(:invalidate_cached_) do |key|
self.attr_cached_.delete(key) if self.attr_cached_[key]
end
return nil
end
def associates_all(*args)
keys.each { |key| associates(key) }
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment