Skip to content

Instantly share code, notes, and snippets.

@zhongfox
Last active February 20, 2017 06:16
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zhongfox/f6ef4684f72215f837f7731f001ec16f to your computer and use it in GitHub Desktop.
Save zhongfox/f6ef4684f72215f837f7731f001ec16f to your computer and use it in GitHub Desktop.
Data Service Ruby Core
module DataService
RELATION_ID = 'relation'
module DataApi
def self.included base
base.singleton_class.send :attr_accessor, # private method
:json_attributes, # 数据模型的json属性定义
:expire_time, # 数据模型的过期时间
:model_class, # 数据模型对应的Activerecord, 默认值是根据类名推断, 可以在这里覆盖
:cache_key # 缓存的key, 有默认值, 通常不需要设置
end
# json_attributes 的组装过程
def attrs_map
klass.json_attributes.inject({}) do |target, attr|
target[attr] = respond_to?(attr) ? send(attr) : model.send(attr)
target
end
end
def klass
is_a?(Class) ? self.singleton_class : self.class
end
def cache_key_with_namespace
"data_service:#{klass.cache_key}:#{id}"
end
def save
return nil unless model # 如果找不到AD对象
json_string = attrs_map.to_json
Redis.deal_service.setex(cache_key_with_namespace, klass.expire_time, json_string)
json_string
end
def delete
Redis.deal_service.del(cache_key_with_namespace)
end
def relation?
id == RELATION_ID
end
end
class Base
attr_accessor :model, :id
# Base#new通常只会在实例型数据上使用
def initialize id
self.id = id
self.model = self.class.model_class.find_by_id id #找到实例型数据对应的AD对象
end
class << self
def inherited subclass
subclass.include DataApi
subclass.singleton_class.include DataApi
# model_class的默认值
name = subclass.name.demodulize
top_model = Object.const_get(name)
name_key = name.downcase
# 设置实例型数据模型的model_class和cache_key
subclass.model_class = top_model
subclass.cache_key = name_key
# 设置关系型数据模型的model_class和cache_key
subclass.singleton_class.model_class = top_model
subclass.singleton_class.cache_key = name_key
# 关系型数据模型的id是固定的字符串relation
subclass.send(:define_singleton_method, :id) { RELATION_ID }
subclass.send(:define_singleton_method, :model) { top_model }
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment