2016-04-06 1 views
0

Предположим, у меня есть модель User с флагом boolean под названием email_notifications. Это позволяет нам знать, должен ли этот пользователь получать уведомления по электронной почте из приложения.Затраты на постоянную проверку связанной с ней вложенной модели (действительно ли результаты кэша activerecord?)

Недавно я переместил все эти флаги и настройки в отдельный подмодельный вызов Preference, чтобы убрать его от основной модели пользователя. A Userhas_onePreference.

class User < ActiveRecord::Base 
    has_one :preference, dependent: :destroy 
    accepts_nested_attributes_for :preference 

    scope :email_recipients, -> { where(preference: { email_notification: true}) } 

    def can_receive_email? 
    preference.email_notification 
    end 
end 

Как вы можете видеть, у меня есть вспомогательная область и вспомогательный метод на модели.

Однако теперь, когда он живет в другой таблице, я всегда запрос Ассоциации :preference первым, а затем получить значение мне нужно. Он не доступен непосредственно из модели User.

Является ли это считается плохой практикой? Или Rails помогает и кэширует связанные модели, поэтому ему не нужно повторно запрашивать каждый раз? Мне нравится организовывать различные конфигурации в отдельной модели, и я думаю, что это хорошая практика, но эта потенциальная стоимость постоянного повторного запроса останавливает меня.

Спасибо!

EDIT:

Я знаю, что я могу сделать User.includes(:preference).blah_blah, однако я хочу, чтобы избежать обновления этого в каждом месте, где я называю пользователя, и это не всегда может быть известно заранее ли я 'm собирается запросить подмодель и необходимо будет указать .includes()

ответ

1

Ассоциации рельсов сохраняются в памяти после их обращения, поэтому вызов user.preference не попадет в базу данных, за исключением случаев, когда она ссылается в первый раз.

Также, includes не имеет большого эффекта в этом случае, так как это has_one. includes обычно полезен для интенсивной загрузки многих ассоциаций в одном более крупном запросе, а не при ударе базы данных каждый раз, когда вызывается дочерний объект.

 Смежные вопросы

  • Нет связанных вопросов^_^