Rails - вложенные включения в Active Records?

166

У меня есть список событий, которые я получаю. Я пытаюсь включить каждого пользователя, связанного с этим событием, и каждый профиль, связанный с каждым пользователем. Пользователи включены, но не их профили.

Как бы я это сделал

Event.includes(:users [{profile:}])

Документы, кажется, не ясны: http://guides.rubyonrails.org/active_record_querying.html

aryaxt
источник

Ответы:

406

Я считаю, что следующее должно работать для вас.

Event.includes(users: :profile)

Если вы хотите включить ассоциацию (назовем ее C) из уже включенной ассоциации (назовем ее B), вы должны использовать приведенный выше синтаксис. Однако, если вы хотите включить также D, который также является ассоциацией с B, тогда вы должны использовать массив, как показано в примере в Руководстве по Rails .

A.includes(bees: [:cees, :dees])

Вы можете продолжать вкладывать такие включения (если вам это действительно нужно). Скажите, что A также связан с Z, и что C связан с E и F.

A.includes( { bees: [ { cees: [:ees, :effs] }, :dees] }, :zees)

И для забавы, мы также скажем, что E связан с J и X, и что D связан с Y.

A.includes( { bees: [ { cees: [ { ees: [:jays, :exes] }, :effs] }, { dees: :wise } ] }, :zees)
Джо Кеннеди
источник
11
Как бы вы добавили условия для включенных модулей ..? :)
Arup Rakshit
1
как добавить туда заказ?
Флориан Видтманн
6
Это один из тех волшебных ответов, которые я нашел раз в несколько лет, и каждый раз спасает мою задницу. Вот как должны выглядеть документы
Эндрю
2
Чтобы сделать это руководство самым утомительным: A.includes( { bees: { cees: {:dees, :ees} } })- для русской кукольной конструкции (например, А включает в себя б, что включает в себя с ... и т. Д.)
Александр Горг
2
добавить условияA.includes(bees: :cees).where(bees: { cees: { flagged: false }}).order("a.bees DESC").order("a.cees ASC")
Фабрицио Бертольо
14

Если кто-то делает respond_toблок для создания вложенного json, вы можете сделать что-то вроде:

respond_to do |f|
  f.json do
    render json: event.to_json(include: {users: {include: :profile} }), status: :ok
  end
end
Blaskovicz
источник
1
Я думаю, что вы имеете в виду as_json- в противном случае это отображает строку JSON.
Meekohi
10

Пожалуйста, обратитесь к решению Джо Кеннеди.

Вот более читаемый пример (для будущего меня).

includes(
  :product,
  :package, {
    campaign: [
      :external_records,
      { account: [:external_records] },
      { agency: [:external_records] },
      :owner,
      :partner,
    ]
  }
)
aschyiel
источник