Rails 3.1 Проблемы с картой идентичности?
Кто-нибудь знает ключевые проблемы, связанные с функцией Rails 3.1 IdentityMap, которая вынудила отключить эту функцию по умолчанию? Я уверен, что есть небольшие специфические проблемы, но есть ли какие-либо серьезные проблемы, о которых должен знать каждый, прежде чем включать его для уже созданного приложения Rails 3.1?
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.
Мне известны две незначительные проблемы:
Если вы наследуете модели и хотите переключиться с одной опечатки объекта на другую, то сначала вам нужно удалить свой объект из карты идентичности, а затем создать новый объект. Пример:
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
Мое мнение таково, что идентификационная карта может быть использована, но частично. Не рекомендуется включать его по умолчанию для каждого отдельного объекта, но будет полезно включить его для конкретных моделей. Скажем, у вас есть таблица языков, которая представляет собой довольно статичные данные или может быть по странам. Почему бы не загрузить их все на карту личности. Но с динамическими данными (такими как пользователи или что-то другое, которые постоянно меняются) нет необходимости хранить их в памяти.