Skip to content

Instantly share code, notes, and snippets.

@mimosz
Created June 7, 2011 08:18
Show Gist options
  • Save mimosz/1011887 to your computer and use it in GitHub Desktop.
Save mimosz/1011887 to your computer and use it in GitHub Desktop.
Mongoid counter cache
## 引入文件
# require 'mongoid/counter_cache'
## 插入Document行後
# include Mongoid::Relations::CounterCache
## 默認
# referenced_in :person, :inverse_of => :posts, :counter_cache => true
## 自定義
# referenced_in :person, :inverse_of => :posts, :counter_cache => :posts_count
module Mongoid
module Relations
module CounterCache
extend ActiveSupport::Concern
module ClassMethods
# 計數器
def counter_cache(metadata)
if metadata.counter_cache?
# 計數器字段
counter_name = if metadata.counter_cache.to_s != 'true'
metadata.counter_cache.to_s
else
"#{metadata.inverse_of}_count"
end
# 遞增
set_callback(:create, :after) do |document|
relation = document.send(metadata.name)
if relation
relation.inc(counter_name.to_sym, 1) if relation.class.fields.keys.include?(counter_name)
end
end
# 遞減
set_callback(:destroy, :after) do |document|
relation = document.send(metadata.name)
if relation && relation.class.fields.keys.include?(counter_name)
relation.inc(counter_name.to_sym, -1)
end
end
end
end
# 數據關係
def referenced_in(name, options = {}, &block)
characterize(name, Referenced::In, options, &block).tap do |meta|
relate(name, meta)
reference(meta)
autosave(meta)
counter_cache(meta) # 計數器
validates_relation(meta)
end
end
alias :belongs_to_related :referenced_in
alias :belongs_to :referenced_in
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment