在gem中转换ActiveRecord的扩展名

这个扩展为所有app模型创建了cache_find方法(我使用这篇文章创建了这个)。

配置/ 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_findflush_findcached_find_by_nameflush_find_by_name ……你得到它。

我需要帮助:

  1. model_caching gem中测试Rails.cache方法。
  2. 创建代码以基于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代码 。

您不必破解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中自动包含扩展名,我认为最好将它明确地包含在您要使用它的模型中。

要动态添加代码,您需要破解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,..等)

希望这可以帮助 !