Есть ли способ получить доступ к объекту Parent, который вызвал одноэлементный метод?
Учитывая следующий функциональный фрагмент, у меня возникли проблемы с уменьшением запросов к базе данных:
class User < ApplicationRecord
belongs_to :account
def self.do_something
self.find_each do |user|
puts "#{self.new.account.name}:#{user.name} did something"
end
end
end
class Account < ApplicationRecord
has_many :users
end
a = Account.first
puts 'starting'
a.users.do_something
Загрузка учетной записи (0,4 мс) ВЫБЕРИТЕ "account".* FROM "account" WHERE "account". "Id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]]
начало
Загрузка учетной записи (0,3 мс) ВЫБЕРИТЕ "account".* FROM "account" WHERE "account". "Id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]]
Тест: пользователь сделал что-то
Загрузка учетной записи (0,3 мс) ВЫБЕРИТЕ "account".* FROM "account" WHERE "account". "Id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]]
Тест: пользователь сделал что-то
Загрузка учетной записи (0,3 мс) ВЫБЕРИТЕ "account".* FROM "account" WHERE "account". "Id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]]
Тест: пользователь сделал что-то
Загрузка учетной записи (0,3 мс) ВЫБЕРИТЕ "account".* FROM "account" WHERE "account". "Id" = $1 LIMIT $2 [["id", 1], ["LIMIT", 1]]
Тест: пользователь сделал что-то
Вы можете видеть, что модель учетной записи выбирается из базы данных для каждого пользователя!
Я надеялся использовать что-то вроде self.account
в методе Singleton для ссылки на исходную учетную запись, но связь по умолчанию явно не существует, поэтому в настоящее время я использую self.new.account
,
Могу ли я получить оригинальную модель учетной записи, сохраненную в a
изнутри self.do_something
? Очевидно, я могу передать учетную запись в параметре, но это кажется утомительным, особенно если я могу добавить аргументы позже...
1 ответ
Внутри вашего find_each
цикл, вы должны быть в состоянии использовать user.account
,
Вне этого цикла я не верю, что есть документированный / поддерживаемый / не исчезающий без предупреждения способ найти объект. В зависимости от вашей версии Rails, что-то вроде self.current_scope.proxy_association.owner
может дать вам ответ, который вам нужен... но предпочитаю user.account
если это вообще возможно: чем больше вы используете частные API, тем сложнее будет обновление в будущем.
В качестве альтернативы рассмотрите возможность использования расширений ассоциаций для определения do_something
метод внутри has_many
только ассоциация - если она не подходит для вызова User.do_something
или же User.where(name: "Bob").do_something
(потому что те не имеют связанных account
), может быть, это не должен быть метод верхнего уровня в конце концов.