Может ли модель принадлежать ребенку ИППП?
У меня есть базовый класс Place
и несколько подклассов с использованием соглашений STI. У меня есть отдельная модель Post
, который belongs_to
один из подклассов Place
:
class Place < ApplicationRecord
end
class SubPlace < Place
has_many :posts, class_name: "SubPlace", foreign_key: "sub_place_id"
end
class Post < ApplicationRecord
belongs_to :sub_place, class_name: "SubPlace", foreign_key: "sub_place_id"
end
Можно сохранить новый Post
запись с помощью консоли Rails, но я получаю следующую ошибку при попытке найти Posts
для конкретного SubPlace
:
ActiveRecord::StatementInvalid (PG::UndefinedColumn: ERROR: column places.sub_place_id does not exist)
Есть ли способ заставить это работать, или мои ассоциации должны относиться только к базовому классу?
Добавлена схема:
create_table "posts", force: :cascade do |t|
t.string "title"
t.bigint "sub_place_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["sub_place_id"], name: "index_posts_on_sub_place_id"
end
create_table "places", force: :cascade do |t|
t.string "name"
t.string "type"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
2 ответа
Лучший способ обработки ассоциаций и STI - просто настроить ассоциации для базового класса:
class Place < ApplicationRecord
end
class SubPlace < Place
has_many :posts, foreign_key: 'place_id', inverse_of: 'place'
end
class AnotherKindOfPlace < Place
has_many :posts, foreign_key: 'place_id', inverse_of: 'place'
end
class Post < ApplicationRecord
belongs_to :place
end
Это делает вещи красивыми и простыми, поскольку Post
не знает или не заботится о том, что есть разные виды мест. Когда вы получаете доступ @post.place
ActiveRecord читает places.type
столбец и создаст правильный подтип.
Если базовый класс Post также имеет ассоциацию, вы просто пишете его так:
class Place < ApplicationRecord
has_many :posts, foreign_key: 'place_id', inverse_of: 'place'
end
ActiveRecord::StatementInvalid (PG::UndefinedColumn: ERROR: столбец place.sub_place_id не существует)
Ваша ассоциация в SubPlace
не действует Вы должны переписать это просто
class SubPlace < Place
has_many :posts
end