В моем текущем приложении rails я извлекаю много данных из базы данных в память, чтобы я мог запускать длительное фоновое задание, при котором я не хочу запускать базу данных каждые 5 секунд.
Все это прекрасно работает, но у меня есть не очень элегантный код, от которого я хотел бы избавиться, если это возможно.
Например, у меня есть ситуация, когда у меня есть модель пользователя, и эта модель пользователя может связываться с другими моделями пользователей в форме контактов, которые, в свою очередь, могут ссылаться на первую модель пользователя и так далее. Это смоделировано следующим образом (спасибо Милане Новоте за его раннюю помощь): -
class User < ActiveRecord::Base
has_many :contact_records, :foreign_key => :owner_id
has_many :contacts, :through => :contact_records, :class_name => "User"
end
class ContactRecord < ActiveRecord::Base
belongs_to :owner, :class_name => "User"
belongs_to :user
end
Так что теперь я могу набрать
user_a_contacts = user_a.contact_records
=> [user_b, user_c]
и получить все контакты для пользователя а. Теперь предположим, что я хочу получить контакты пользователя b через пользователя a (не могу понять почему, но это только пример!)
user_b_contacts = user_a_contacts.first.contact_records
=> [user_a, user_c]
Теперь я могу получить имя пользователя a (извилистым, окольным способом, который никогда не будет использоваться в реальном мире)
user_a_name = user_b_contacts.first.name
=> "Jamie"
Пока все хорошо. Теперь я меняю имя пользователя a
user_a.name = "Sandy"
=> "Sandy"
При повторном обращении к имени пользователя a из базы данных, как и раньше, я получаю
user_a_name = user_b_contacts.first.name
=> "Sandy"
Однако, если я с нетерпением загрузил и сохранил это значение в памяти, я получаю
user_a_name = user_b_contacts.first.name
=> "Jamie"
но выполнение следующего дает мне правильный ответ
user_a.name
=> "Sandy"
Совершенно очевидно, что eager-loading создает разные объекты User для исходных пользователей и те, которые eager-загружаются из объектов ContactRecord.
Итак (наконец-то!) Мой вопрос таков: -
На данный момент я обошел это с помощью
@users.each.detect{|user| user == user_b_contacts.first}
(где @users - загруженный список пользовательских объектов). Есть ли способ, которым я могу обновить загруженные пользователем объекты User вместо этого?
Обратите внимание: -
a) Я жду загрузки с использованием следующего
User.find(:all, :include => [ {:contact_records => :contacts] } ])
б) Очевидно, что это не тот код, с которым я работаю, но было бы еще больше объяснений и объяснений, чтобы показать этот код, и я думаю, что вам достаточно скучно! Поверьте мне, что настоящий пример, который я использую, требует, чтобы эта структура работала правильно, как бы странно это ни выглядело! ;)
в) Я мог ввести опечатки и ошибки при реконструкции примера, но, пожалуйста, игнорируйте их. Все, что мне нужно знать, это возможность перезагрузить загруженных пользователей, не обращаясь к базе данных.
Заранее большое спасибо!
ОБНОВЛЕНИЕ: Как упоминалось ниже, данные модели не будут сохранены в базе данных до самого конца выполнения процесса, поэтому перезагрузка не будет работать, так как данные в базе данных не изменились.