ActiveRecord на самом деле имеет встроенный механизм наследования отдельных таблиц, который вы можете использовать здесь.
Начните с добавления столбца с именем type
в таблицу:
class AddTypeToPoems < ActiveRecord::Migration[5.2]
def change
add_column :poems, :type, :string
add_index :poems, :type
end
end
Затем установите классы для наследования:
class Poem < ApplicationRecord
end
class NewPoem < Poem
# gets its table name from the parent class
end
ActiveRecord автоматически устанавливает столбец type
и даже использует его при извлечении записей:
irb(main):001:0> NewPoem.create
(0.3ms) BEGIN
NewPoem Create (1.3ms) INSERT INTO "poems" ("created_at", "updated_at", "type") VALUES ($1, $2, $3) RETURNING "id" [["created_at", "2019-05-08 19:17:45.086947"], ["updated_at", "2019-05-08 19:17:45.086947"], ["type", "NewPoem"]]
(0.7ms) COMMIT
=> #<NewPoem id: 1, title: nil, created_at: "2019-05-08 19:17:45", updated_at: "2019-05-08 19:17:45", type: "NewPoem">
irb(main):002:0> Poem.first
Poem Load (0.7ms) SELECT "poems".* FROM "poems" ORDER BY "poems"."id" ASC LIMIT $1 [["LIMIT", 1]]
=> #<NewPoem id: 1, title: nil, created_at: "2019-05-08 19:17:45", updated_at: "2019-05-08 19:17:45", type: "NewPoem">
irb(main):003:0>
Таким образом, даже если мы используем Poem.first
, он создает экземпляр NewPoem
из результата. Если вы используете искатели на рельсах подклассов, они автоматически прицеливаются:
irb(main):003:0> NewPoem.all
NewPoem Load (1.8ms) SELECT "poems".* FROM "poems" WHERE "poems"."type" IN ('NewPoem') LIMIT $1 [["LIMIT", 11]]
Если вам нужен только «старый» тип, который вам нужно использовать:
Poem.where(type: [nil, 'Poem'])