感觉Rack::Builder就是个奇怪的存在
Ruby 1.9.3和Ruby 2.0的arity的对比

解决ActiveRecord经常要reload的一种方案

bachue posted @ 2013年4月22日 22:19 in Ruby with tags ruby rails database cache ActiveModel ActiveRecord middleware active_record active_model request , 3219 阅读

我发现写Rails,尤其是测试部分,需要reload的次数相当频繁。比方说

user = users(:xxxxx)
xhr :put, 'change_xxxxx', :id => user.id
user.reload # necessary!
assert user.xxx, xxx
assert user.yyy, yyy

由于这里创建的user对象和被测试的action里的user对象(在内存概念上)不是同一个对象,因此,被测试的action修改了user对象在数据库里的数据,会导致外围的user信息过时,因此必须reload,否则接下来的断言语句都无法通过。

这种情况同样也有可能存在与关联对象上,比如

assert child1.father, child2.father
child1.father.name = 'new name'
child1.save
child2.reload # necessary!
assert child2.father.name, 'new name'

总是写很多reload语句显然很不舒服,为此我今天在回家的地铁上想了一种解决方案,就是在后台全局的部分,以ActiveRecord类名和实例为key简单的缓存一部分数据,这部分数据与数据库里的数据在本次request返回内一致,request结束后自动清除以免内存泄露和影响下一个request。而前面的ActiveRecord对象,本身仅存储那些还未被保存的数据。

方案大致是这样的(以Rails 2.3为例):

require 'active_record'

module ActiveRecord
  class Base
    def request_cache
      self.class.request_cache[self]
    end

    def request_cache=(v)
      self.class.request_cache[self] = v
    end
  end

  class << Base
    def request_cache
      @request_cache ||= Hash.new {|h, k| h[k] = Hash.new {|h, k| h[k] = {}}}
      @request_cache[name]
    end
  end
end

ActionController::Dispatcher.middleware.use(Class.new do
  def initializer(app)
    @app = app
  end

  def call(env)
    @app.call(env)
  ensure
    ActiveRecord::Base.request_cache.clear
  end
end)

这里我把缓存就设计在ActiveRecord的class variable内(三级Hash,分别是类-实例对象-属性名),然后用Middleware的方式去清理缓存,之所以选择用Middleware的方式是因为ActiveRecord原本和HTTP Request是不能发生关联的,否则Console和Unit test里就无法执行了,设计成Middleware则能很好的解决这一问题。

由于选择的三级Hash的设计中没有直接和数据库关联的信息,因此其实也可以用于非ActiveRecord类(唯一要做的可能仅仅是自己实现一种标示方法),毕竟当前可以用于存储的服务早已不止数据库一种了。

至于对于ActiveRecord的修改我现在对ActiveRecord的实现还不够熟悉,无法完成,以后学习这一部分了再说吧。但是大致的思路是这样的:

  • 当从数据库读入数据的时候(包括reload),将缓存里的数据翻新
  • 当保存数据进数据库的时候,将数据同样保存进缓存
  • 当从一个ActiveRecord对象读取属性的时候,现在被当前对象修改过的属性中搜索,如果搜索不到再从缓存里搜索,如果还是搜索不到就采用默认方法

大致就是这些了,其实想法还是很简单的,希望早日自己能把它变成现实。

لی ویوسوہ ہو یار 说:
2021年5月29日 16:22

You have done a great job on this article. It’s very readable and highly intelligent. You have even managed to make it understandable and easy to read. You have some real writing talent. Thank you. click here

لی ویوسوہ ہو یار 说:
2021年6月01日 19:24

Hi there! Nice material, do keep me posted when you post something like this again! I will visit this blog leaps and bounds for more quality posts like it. Thanks... hair transplant singapore

123 movies 说:
2021年6月30日 19:53

e! Nice material, do keep me posted when you post something like this again! I will visit this blog leaps and bounds for more quality po

Pancake Bunny 100X 说:
2021年7月04日 16:53

material, do keep me posted when you post something like

maaz 说:
2021年7月06日 19:05

You will find dissertation online sites via internet settle purchase not surprisingly well-known while in the web pages. 우리카지노

maaz 说:
2021年7月06日 19:46

There are lots of dissertation websites from the net dwell acquire unsurprisingly regarded from the internet websites. 더킹카지노

123movies websites 说:
2021年7月29日 14:46

re lots of dissertation websites from the net dwell acquire unsurpr


登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter