Как запросить базу данных с полиморфной ассоциацией? - PullRequest
1 голос
/ 25 октября 2019

Допустим, в приложении rails (с postgresql) у меня есть эта база данных с полиморфной ассоциацией между work_steps и sub_assemblies / parts: enter image description here

Part.rb

belongs_to :sub_assembly, optional: true
has_many :work_steps, as: :component
belongs_to :site
belongs_to :car

Sub_assembly.rb

has_many :work_steps, as: :component
has_many :parts

work_step.rb

  belongs_to :component, polymorphic: true

Теперь я хочу запросить свою базу данных: я хочу получить список всех рабочих шагов, отфильтрованных с помощьюконкретный массив сайтов и конкретный массив автомобилей. Например, все work_steps, связанные с частями, которые принадлежат сайту A и Car X & Z.

Из-за полиморфной ассоциации с sub_assemblies и той же самой таблицей, которая связана с таблицей деталей, я не могу понять, какчтобы сделать это.

В конце мне нужна связь ActiveRecord. Как бы вы сделали это просто? Я много чего перепробовал, но безуспешно.

Кто-нибудь мне поможет?

Заранее спасибо.

1 Ответ

0 голосов
/ 25 октября 2019

Хорошо, так что work_step - это то, что вы хотите использовать в нескольких моделях.

Итак, внутри миграции для CreateWorkSteps:

t.references :component, polymorphic: true

Это в основном делает

t.integer :component_id # Refers to id (of sub-assembly or part)
t.string :component_type # Refers to type of object (sub-assembly or part)
add_index :work_steps, [:component_type, component_id]

Теперь в вашей модели:

work_step.rb

belongs_to :component, polymorphic: true

sub_assembly.rb

has_many :work_steps, as: :component
has_many :parts

part.rb

has_many :work_steps, as: :component
belongs_to :site
belongs_to :car
belongs_to :sub_assembly, optional: true

Хорошо, поэтому вы хотите запросить базу данных и получить

  • work_steps
  • связан с деталями
  • принадлежит сайту A и Car X и Z

Итак, вот список шагов, которые вы должны сделать в ActiveRecord (I 'Я не собираюсь давать ответ на один запрос, так как это слишком много усилий. Кроме того, порядок шагов находится в логическом порядке, но помните, что запросы ActiveRecord используют ленивую оценку, а запросы SQL оцениваются в определенном порядке.)

  1. # Соединить детали с сайтом и автомобилями
  2. Использовать # Где siteName находится в [A], carName находится в [X, Z]
  3. Теперь вы ЛЕВО соединяетесь с sub_assembly (Таким образом, даже если деталь не имеет sub_assembly_id, она не удаляется).
  4. Теперь это раздражающий шаг. При первом соединении вы захотите объединить parts_id с component_id AND component_type == "Part" (не забудьте добавить в таблицу ваши префиксы при присоединении, например, work_steps.component_id и делайте это с самого начала.)
  5. Для вашегово втором соединении вы захотите объединить sub_assembly_id с component_id AND component_type == "Sub_assembly"
  6. Теперь у вас есть ОГРОМНЫЙ объект ActiveRecord, выберите только то, что делает work_step.

Goodудачи! Я не буду держать вас за руку с заранее написанным ответом, потому что ... потому что мне лень загружаться в Rails, выполнять миграции, создавать модели, заполнять модели, а затем сам писать запрос. ;)

О да, и я все равно закончил тем, что дал один-единственный ответ

...