Rails-ассоциации, использующие массив в качестве foreign_id - PullRequest
0 голосов
/ 01 июня 2019

Я ищу создание ассоциации, в которой модель может создаваться и принадлежать трем различным объектам, но также ссылаться на два других объекта.

Например, у меня есть модель перформанс , в которой три типа моделей могут создавать спектакль: место проведения , исполнитель , группа . Тем не менее, исполнение также должно ссылаться на два других, например, если место проведения создает представление, оно должно перечислить исполнителя или группу, которая будет выполнять. И если артист создает спектакль, то артист должен указать место, где он будет выступать.

Итак, я начинаю с чего-то вроде этого:

class CreatePerformances < ActiveRecord::Migration[6.0]
  def change
    create_table :performances, id: :uuid do |t|
      t.belongs_to :venue, index: true
      t.belongs_to :artist, index: true
      t.belongs_to :band, index: true
      t.timestamps
    end
  end
end

Однако, если владелец места создает спектакль и выполняет две отдельные полосы, мне нужно иметь массив полос в столбце band_id . Но когда я делаю это (t.belongs_to :band, type: :uuid, array: true, default: [], index: true) и добавляю группу в массив band_id, а затем делаю band.performances, я получаю: ActiveRecord::StatementInvalid (PG::InvalidTextRepresentation: ERROR: malformed array literal:

Могу ли я сделать столбец ассоциации массивом, и при этом иметь возможность использовать функции ассоциации Rails, или это невозможно или даже плохо, и если да, то как?

Кроме того, я использую postgresql, и если у вас есть более элегантные способы выполнения вышесказанного, это также приветствуется.

1 Ответ

5 голосов
/ 01 июня 2019

Полагаю, лучше использовать отношение has_many.

Если в спектакле может быть много групп, то он не "принадлежит" группе, у него "много" групп.

Таким образом, вы можете использовать отношения «есть и принадлежит многим» или «есть много: через» между выступлениями и группами.Проверьте различия здесь https://guides.rubyonrails.org/association_basics.html#choosing-between-has-many-through-and-has-and-belongs-to-many

Самый простой из двух вариантов настройки - HABTM:

class Band
  has_and_belongs_to_many :performances

class Performance
  has_and_belongs_to_many :bands

Вам нужна таблица, поэтому добавьте мираж, который делает это:

create_table :bands_performances, id: false do |t|
  t.references :band, index: true
  t.references :performance, index: true
end

https://guides.rubyonrails.org/association_basics.html#creating-join-tables-for-has-and-belongs-to-many-associations

Проверьте руководство: если вам нужны дополнительные поля, вам может понадобиться модель соединения и использовать has_many: through.Вы знаете контекст лучше, чем кто-либо.

...