Есть ли способ получить доступ к объекту 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), может быть, это не должен быть метод верхнего уровня в конце концов.

Другие вопросы по тегам