【发布时间】:2011-08-02 00:03:04
【问题描述】:
有谁知道 Rails 3.1 IdentityMap 功能的关键问题导致该功能默认被禁用?我确信存在一些小的特定问题,但是在为已经构建的 Rails 3.1 应用程序启用它之前,是否有任何人应该注意的重大问题?
【问题讨论】:
标签: ruby-on-rails ruby-on-rails-3 identity-map
有谁知道 Rails 3.1 IdentityMap 功能的关键问题导致该功能默认被禁用?我确信存在一些小的特定问题,但是在为已经构建的 Rails 3.1 应用程序启用它之前,是否有任何人应该注意的重大问题?
【问题讨论】:
标签: ruby-on-rails ruby-on-rails-3 identity-map
# Active Record Identity Map does not track associations yet. For example:
#
# comment = @post.comments.first
# comment.post = nil
# @post.comments.include?(comment) #=> true
#
# Ideally, the example above would return false, removing the comment object from the
# post association when the association is nullified. This may cause side effects, as
# in the situation below, if Identity Map is enabled:
#
# Post.has_many :comments, :dependent => :destroy
#
# comment = @post.comments.first
# comment.post = nil
# comment.save
# Post.destroy(@post.id)
#
# Without using Identity Map, the code above will destroy the @post object leaving
# the comment object intact. However, once we enable Identity Map, the post loaded
# by Post.destroy is exactly the same object as the object @post. As the object @post
# still has the comment object in @post.comments, once Identity Map is enabled, the
# comment object will be accidently removed.
#
# This inconsistency is meant to be fixed in future Rails releases.
【讨论】:
当您查看 the documentation 时,提出的主要问题是 Identity Map 中管理的对象还不能处理关联,因此它现在还没有准备好在现实世界中使用。
文档明确指出该功能仍在开发中,因此没有人真正应该在野外使用它。
【讨论】:
我知道的两个小问题是:
如果你继承模型,并且你想从一个拼写错误的对象切换到另一个,那么首先你需要从身份映射中删除你的对象,然后创建一个新对象。示例:
class A < ActiveRecord::Base
end
class B < ActiveRecord::Base
end
a = A.create!
a.update_attribute :type, 'B'
b = B.find a.id
#=> #<A:...>
ActiveRecord::IdentityMap.remove(a) if ActiveRecord::IdentityMap.enabled?
b = B.find a.id
#=> #<B:...>
另一个小问题是身份映射可能会在测试中遇到问题。因为它不会在每次测试后截断其存储库。为此,需要将其添加到测试框架配置中。 Rspec 示例:
RSpec.configure do |config|
config.after :each do
DatabaseCleaner.clean
ActiveRecord::IdentityMap.clear
end
end
我的观点是可以使用身份映射,但只是部分使用。默认情况下为每个单个对象启用它是一个坏主意,但将它启用到特定模型将是一个好主意。比如说,你有一个语言表,它是相当静态的数据,或者可能是按国家/地区划分的。为什么不将它们全部加载到身份映射中。但是,对于动态数据(如用户或其他不断变化的数据),无需将其存储在内存中。
【讨论】: