此扩展程序为所有应用模型创建cache_find
方法(我使用this post创建此方法)。
配置/ active_record_extension.rb
require 'active_support/concern'
module ActiveRecordExtension
extend ActiveSupport::Concern
# add your instance methods here
def flush_find
Rails.cache.delete([self.class.name, :cached_find, id])
end
included do
after_commit :flush_find
end
module ClassMethods
def cached_find id
Rails.cache.fetch([self.name, :cached_find, id]) { self.find(id) }
end
end
end
# include the extension
ActiveRecord::Base.send(:include, ActiveRecordExtension)
我将此代码转换为gem并添加到此repo。
所以我想动态添加这些方法,如下所示:
class User << ActiveRecord::Base
# id, name, email, age...
cached :find, :find_by_name, :find_by_email
end
以上代码应该生成cached_find
,flush_find
,cached_find_by_name
,flush_find_by_name
......你明白了。
我需要帮助:
Rails.cache
gem。model_caching
个方法
cached
方法参数动态地将方法添加到应用模型。有些链接帮助了我但并不满足所有要求:
https://github.com/radar/guides/blob/master/extending-active-record.md
http://railscasts.com/episodes/245-new-gem-with-bundler
http://guides.rubyonrails.org/plugins.html
可以随意克隆并改进gem code。
答案 0 :(得分:3)
您不必破解ActiveRecord :: Base。您可以添加Marc-Alexandre所说的内容,如下所示:
module ActiveRecordExtension
extend ActiveSupport::Concern
...
module ClassMethods
def cached(*args)
define_method "cached_#{arg.to_s}" do
# do whatever you want to do inside cached_xx
end
define_method "flush_#{arg.to_s}" do
# do whatever you want to to inside flush_xx
end
end
end
end
另外,我不会直接在ActiveRecord中自动包含扩展名,我认为最好将它明确地包含在您要使用它的模型中。
答案 1 :(得分:1)
要动态添加代码,您需要破解ActiveRecord :: Base类。在另一个文件中(通常放在lib / core_ext中),您可以执行以下操作:
ActiveRecord::Base.class_eval do
def self.cached(*args)
args.each do |arg|
define_method "cached_#{arg.to_s}" do
# do whatever you want to do inside cached_xx
end
define_method "flush_#{arg.to_s}" do
# do whatever you want to to inside flush_xx
end
end
end
end
它的作用基本上是将所有参数用于缓存(:find,:find_by_name等)并定义两个方法(cache_find,cache_find_by_name)和flush_find,..等)
希望这有帮助!