Многие ко многим между категориями и другими моделями

Допустим, у нас есть два таких класса:

class Book < ActiveRecord::Base
end

class Magazine < ActiveRecord::Base
end

У этих объектов может быть много категорий, и в каждой категории может быть много книг или много журналов, но не одновременно книги и журналы.

Один из способов справиться с этим — создать две отдельные модели категорий, а именно BookCategory и MagazineCategory, а затем создать отношение «многие ко многим».

Мне было интересно, есть ли способ сделать это только с помощью одной модели Category.

Я думал о полиморфизме, но он не работает со многими ко многим.

Я попробовал STI, как показано ниже, но не смог его взломать:

class Book < ActiveRecord::Base
  has_many :categorizations
  has_many :book_categories, through: :categorizations
end

class Category < ActiveRecord::Base
end

class BookCategory < Category
  has_many :categorizations
  has_many :books, through: :categorizations, source: :categorizable, source_type: "Book"
end

Но это приводит к следующему SQL, который неверен:

SELECT "books".* FROM "books" INNER JOIN "categorizations"
ON "books"."id" = "categorizations"."categorizable_id"
WHERE "categorizations"."book_category_id" = ?
AND "categorizations"."categorizable_type" = ?  [[nil, 1], ["categorizable_type", "Book"]]

Должен ли я просто сдаться и сделать это, используя две отдельные таблицы категорий, или есть способ сделать это с помощью STI или полиморфизма? И даже если способ есть, логично ли его использовать?

P.S. Я знаю, что на SO есть похожие сообщения, и я пытался их прочитать и понять. Никто из них толком не помог.


person hattenn    schedule 28.10.2015    source источник
comment
Можете ли вы также включить свою модель Categiorization? source: categorizable заставляет меня думать, что вы используете STI в этой таблице, хотя в вашем посте об этом не упоминается.   -  person Lanny Bose    schedule 29.10.2015
comment
То, что вы хотите, потребует некоторых сложных проверок (и ограничений базы данных, если вы действительно хотите иметь надежные данные). На мой взгляд, было бы проще иметь отдельные типы категорий (BookCategory и MagazineCategory). Это похоже на то, что моя команда делала в нескольких случаях, и мы не пожалели об этом.   -  person Wizard of Ogz    schedule 29.10.2015


Ответы (1)


class Book < ActiveRecord::Base
  has_and_belongs_to_many :book_categories, join_table: :books_categories
end

class Category < ActiveRecord::Base
end

class BookCategory < Category
  has_and_belongs_to_many: books, join_table: :books_categories
end

Установите таблицу в соответствии с ассоциацией has_and_belongs_to_many

person wesley6j    schedule 28.10.2015
comment
Спасибо, но я хотел узнать, есть ли логичный и эффективный способ сделать это, используя только одну таблицу. Я знаю многих ко многим. - person hattenn; 29.10.2015
comment
@hattenn Это решение для одной таблицы с STI. Создайте таблицу categories со строковым столбцом type. - person wesley6j; 29.10.2015
comment
Я не понимаю, как с помощью этого метода создать таблицу соединений (кроме создания отдельных таблиц соединений для каждого типа категории). - person hattenn; 29.10.2015
comment
@hattenn Чтобы использовать единую таблицу соединений, используйте полиморфную таблицу соединений. - person wesley6j; 29.10.2015
comment
Сначала казалось, что это работает, но есть проблемы. Я все еще выбираю это как ответ на указанное направление. - person hattenn; 29.10.2015