Rails предварительно загружает ассоциацию

avatar
gv1507
8 апреля 2018 в 04:45
1984
2
-2

У меня возникли проблемы с предварительной загрузкой ассоциации belongs_to.

Рассматриваемая модель имеет следующую связь

class Order < ActiveRecord::Base
  belongs_to :user_name, -> { select(:id, :name) }, class_name: "User", :foreign_key => 'user_id'
end

Приведенная выше ассоциация работает нормально и разрешается, как и ожидалось.

Я хочу вернуть user.id и user.name вместе с order. Как предварительно загрузить ассоциацию user_name.

Я попробовал Order.includes(:user_name), но это не сработало, как ожидалось.

Источник
Eyeslandic
8 апреля 2018 в 10:58
0

Это выглядит странно, почему бы вам просто не сделать belongs_to :user, а затем Order.find(1).user.name?

praga2050
8 апреля 2018 в 11:47
0

Вы не должны выбирать в отношениях. Вы можете добавить область в модель

Martin Zinovsky
8 апреля 2018 в 18:46
0

Что именно не работало с Order.includes(:user_name)?

Ответы (2)

avatar
Martin Zinovsky
8 апреля 2018 в 19:11
1

Я бы изменил связь только на:

class Order < ActiveRecord::Base
  belongs_to :user
end

и выберите users.id и users.name в другом месте. Это делает ваш код более гибким.


Как предварительно загрузить ассоциацию

ActiveRecord предоставляет несколько способов сделать это:

  1. Предварительная загрузка. Загружает данные ассоциации в отдельный запрос. С preload всегда генерирует два sql, вы не можете использовать предварительно загруженную таблицу в где условие.
  2. Включает. По умолчанию загружает данные ассоциации в отдельный запрос, как и предварительная загрузка. Но с дополнительными ссылками call он переключается с использования двух отдельных запросов на создание одиночный LEFT OUTER JOIN. Таким образом, вы можете использовать таблицы ассоциаций в условии where.
  3. Нетерпеливая загрузка. Загружает ассоциацию в одном запросе, используя LEFT OUTER JOIN.

Вот несколько полезных статей:

Предварительная загрузка, предварительная загрузка, включение и объединение

Понимание соединений ActiveRecord, включений, предварительной загрузки и нетерпеливой загрузки

avatar
praga2050
8 апреля 2018 в 11:58
0

Попробуйте добавить область, как показано ниже

scope : user_name_id, -> { joins(:user_name).select( 'user_names.id, user_names.name' ).collect{|c| [c.id, c.name]} }