JoJoS
JoJoS

Reputation: 2041

How to change the foreign type for a polymorphic model

I have a legacy database that I want to cleanup the model. The database is shared between apps so I can't modify it.

I have a model named Catalog that relies in a book_catalogs table. I do somethings like that to use the good table : self.table_name = 'book_catalogs'

The problem is when I want to define the belongs_to :catalogable, polymorphic: true in the model CatalogBook, I can't find a way to override the foreign_type to BookCatalog.

Here is a subset of my model:

class Catalog
  self.table_name = 'book_catalogs'

  has_many :books, through: :catalogs_books
end 

class VirtualCatalog
  has_many :books, through: :catalogs_books
end 

class Book
  has_many :catalogs, through: :catalogs_books
end 

class CatalogsBook
  belongs_to :book
  belongs_to :catalogable, polymorphism: true, foreign_key: :catalog_id
end 

And in my database, I have this:

catalogs_books
+------------+------------------+---------+
| catalog_id | catalogable_type | book_id |
+------------+------------------+---------+
| 15842      | BookCatalog      | 4567894 |
+------------+------------------+---------+

An ActiveRecord query example:

SELECT "books".*
FROM "books"
INNER JOIN "catalogs_books" ON "books"."id" = "catalogs_books"."book_id"
WHERE "catalogs_books"."catalog_id" = $1
AND "catalogs_books"."catalogable_type" = $2
[["catalog_id", 1], ["catalogable_type", "Catalog"]]`

How can I replace the catalogable_type Catalog by BookCatalog ?

Upvotes: 4

Views: 910

Answers (1)

Neil Atkinson
Neil Atkinson

Reputation: 774

You use the foreign_type option:

class CatalogsBook
  belongs_to :book
  belongs_to :catalogable, polymorphism: true, foreign_type: :book_catalog, foreign_key: :catalog_id
end

Upvotes: 1

Related Questions